summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/extension/internal/image-resolution.cpp379
1 files changed, 200 insertions, 179 deletions
diff --git a/src/extension/internal/image-resolution.cpp b/src/extension/internal/image-resolution.cpp
index 53fcc0fbf..a17a2bb30 100644
--- a/src/extension/internal/image-resolution.cpp
+++ b/src/extension/internal/image-resolution.cpp
@@ -27,27 +27,30 @@ namespace Extension {
namespace Internal {
ImageResolution::ImageResolution(char const *fn) {
- ok_ = false;
-
- readpng(fn);
- if (!ok_)
- readexif(fn);
- if (!ok_)
- readexiv(fn);
- if (!ok_)
- readjfif(fn);
+ ok_ = false;
+
+ readpng(fn);
+ if (!ok_) {
+ readexiv(fn);
+ }
+ if (!ok_) {
+ readjfif(fn);
+ }
+ if (!ok_) {
+ readexif(fn);
+ }
}
bool ImageResolution::ok() const {
- return ok_;
+ return ok_;
}
double ImageResolution::x() const {
- return x_;
+ return x_;
}
double ImageResolution::y() const {
- return y_;
+ return y_;
}
@@ -57,60 +60,62 @@ double ImageResolution::y() const {
#include <png.h>
static bool haspngheader(FILE *fp) {
- unsigned char header[8];
- if (fread(header, 1, 8, fp)!=8)
- return false;
+ unsigned char header[8];
+ if ( fread(header, 1, 8, fp) != 8 ) {
+ return false;
+ }
- fseek(fp, 0, SEEK_SET);
-
- if (png_sig_cmp(header, 0, 8))
- return false;
+ fseek(fp, 0, SEEK_SET);
+
+ if (png_sig_cmp(header, 0, 8)) {
+ return false;
+ }
- return true;
+ return true;
}
// Implementation using libpng
void ImageResolution::readpng(char const *fn) {
- FILE *fp = fopen(fn, "rb");
- if (!fp)
- return;
+ FILE *fp = fopen(fn, "rb");
+ if (!fp)
+ return;
- if (!haspngheader(fp)) {
- fclose(fp);
- return;
- }
+ if (!haspngheader(fp)) {
+ fclose(fp);
+ return;
+ }
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
- if (!png_ptr)
- return;
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!png_ptr) {
- png_destroy_read_struct(&png_ptr, 0, 0);
- return;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, 0);
- fclose(fp);
- return;
- }
+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!png_ptr)
+ return;
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_read_struct(&png_ptr, 0, 0);
+ return;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+ fclose(fp);
+ return;
+ }
- png_init_io(png_ptr, fp);
- png_read_info(png_ptr, info_ptr);
+ png_init_io(png_ptr, fp);
+ png_read_info(png_ptr, info_ptr);
- png_uint_32 res_x, res_y;
- int unit_type;
- png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type);
+ png_uint_32 res_x, res_y;
+ int unit_type;
+ png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type);
- png_destroy_read_struct(&png_ptr, &info_ptr, 0);
- fclose(fp);
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+ fclose(fp);
- if (unit_type == PNG_RESOLUTION_METER) {
- ok_ = true;
- x_ = res_x * 2.54/100;
- y_ = res_y * 2.54/100;
- }
+ if (unit_type == PNG_RESOLUTION_METER) {
+ ok_ = true;
+ x_ = res_x * 2.54 / 100;
+ y_ = res_y * 2.54 / 100;
+ }
}
#else
@@ -126,63 +131,71 @@ void ImageResolution::readpng(char const *) {
#include <libexif/exif-data.h>
static double exifDouble(ExifEntry *entry, ExifByteOrder byte_order) {
- switch (entry->format) {
- case EXIF_FORMAT_BYTE:
- return double(entry->data[0]);
- case EXIF_FORMAT_SHORT:
- return double(exif_get_short(entry->data, byte_order));
- case EXIF_FORMAT_LONG:
- return double(exif_get_long(entry->data, byte_order));
- case EXIF_FORMAT_RATIONAL: {
- ExifRational r = exif_get_rational(entry->data, byte_order);
- return double(r.numerator)/double(r.denominator);
- }
- case EXIF_FORMAT_SBYTE:
- return double(*(signed char *)entry->data);
- case EXIF_FORMAT_SSHORT:
- return double(exif_get_sshort(entry->data, byte_order));
- case EXIF_FORMAT_SLONG:
- return double(exif_get_slong(entry->data, byte_order));
- case EXIF_FORMAT_SRATIONAL: {
- ExifSRational r = exif_get_srational(entry->data, byte_order);
- return double(r.numerator)/double(r.denominator);
- }
- case EXIF_FORMAT_FLOAT:
- return double(((float *)entry->data)[0]);
- case EXIF_FORMAT_DOUBLE:
- return ((double *)entry->data)[0];
- default:
- return nan(0);
- }
+ switch (entry->format) {
+ case EXIF_FORMAT_BYTE: {
+ return double(entry->data[0]);
+ }
+ case EXIF_FORMAT_SHORT: {
+ return double(exif_get_short(entry->data, byte_order));
+ }
+ case EXIF_FORMAT_LONG: {
+ return double(exif_get_long(entry->data, byte_order));
+ }
+ case EXIF_FORMAT_RATIONAL: {
+ ExifRational r = exif_get_rational(entry->data, byte_order);
+ return double(r.numerator) / double(r.denominator);
+ }
+ case EXIF_FORMAT_SBYTE: {
+ return double(*(signed char *)entry->data);
+ }
+ case EXIF_FORMAT_SSHORT: {
+ return double(exif_get_sshort(entry->data, byte_order));
+ }
+ case EXIF_FORMAT_SLONG: {
+ return double(exif_get_slong(entry->data, byte_order));
+ }
+ case EXIF_FORMAT_SRATIONAL: {
+ ExifSRational r = exif_get_srational(entry->data, byte_order);
+ return double(r.numerator) / double(r.denominator);
+ }
+ case EXIF_FORMAT_FLOAT: {
+ return double(((float *)entry->data)[0]);
+ }
+ case EXIF_FORMAT_DOUBLE: {
+ return ((double *)entry->data)[0];
+ }
+ default: {
+ return nan(0);
+ }
+ }
}
// Implementation using libexif
void ImageResolution::readexif(char const *fn) {
- ExifData *ed;
- ed = exif_data_new_from_file(fn);
- if (!ed)
- return;
- ExifByteOrder byte_order = exif_data_get_byte_order(ed);
-
- ExifEntry *xres = exif_content_get_entry(ed->ifd[EXIF_IFD_0],
- EXIF_TAG_X_RESOLUTION);
- ExifEntry *yres = exif_content_get_entry(ed->ifd[EXIF_IFD_0],
- EXIF_TAG_Y_RESOLUTION);
- ExifEntry *unit = exif_content_get_entry(ed->ifd[EXIF_IFD_0],
- EXIF_TAG_RESOLUTION_UNIT);
- if (xres && yres) {
- x_ = exifDouble(xres, byte_order);
- y_ = exifDouble(yres, byte_order);
- if (unit) {
- double u = exifDouble(unit, byte_order);
- if (u==3) {
- x_ *= 2.54;
- y_ *= 2.54;
- }
+ ExifData *ed;
+ ed = exif_data_new_from_file(fn);
+ if (!ed)
+ return;
+
+ ExifByteOrder byte_order = exif_data_get_byte_order(ed);
+
+ ExifEntry *xres = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_X_RESOLUTION);
+ ExifEntry *yres = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_Y_RESOLUTION);
+ ExifEntry *unit = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_RESOLUTION_UNIT);
+
+ if ( xres && yres ) {
+ x_ = exifDouble(xres, byte_order);
+ y_ = exifDouble(yres, byte_order);
+ if (unit) {
+ double u = exifDouble(unit, byte_order);
+ if ( u == 3 ) {
+ x_ *= 2.54;
+ y_ *= 2.54;
+ }
+ }
+ ok_ = true;
}
- ok_ = true;
- }
- exif_data_free(ed);
+ exif_data_free(ed);
}
#else
@@ -196,43 +209,43 @@ void ImageResolution::readexif(char const *) {
#if IR_TRY_EXIV
void ImageResolution::readexiv(char const *fn) {
- Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(fn);
- if (!image.get())
- return;
-
- image->readMetadata();
- Exiv2::ExifData &exifData = image->exifData();
- if (exifData.empty())
- return;
-
- Exiv2::ExifData::const_iterator end = exifData.end();
- bool havex = false;
- bool havey = false;
- bool haveunit = false;
- int unit;
- for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
- if (ok_)
- break;
- if (i->tag()==0x011a) {
- // X Resolution
- x_ = i->toFloat();
- havex = true;
- } else if (i->tag()==0x011b) {
- // Y Resolution
- y_ = i->toFloat();
- havey = true;
- } else if (i->tag()==0x0128) {
- unit = i->toLong();
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(fn);
+ if (!image.get())
+ return;
+
+ image->readMetadata();
+ Exiv2::ExifData &exifData = image->exifData();
+ if (exifData.empty())
+ return;
+
+ Exiv2::ExifData::const_iterator end = exifData.end();
+ bool havex = false;
+ bool havey = false;
+ bool haveunit = false;
+ int unit;
+ for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
+ if (ok_)
+ break;
+ if ( i->tag() == 0x011a ) {
+ // X Resolution
+ x_ = i->toFloat();
+ havex = true;
+ } else if ( i->tag() == 0x011b ) {
+ // Y Resolution
+ y_ = i->toFloat();
+ havey = true;
+ } else if ( i->tag() == 0x0128 ) {
+ unit = i->toLong();
+ }
+ ok_ = havex && havey && haveunit;
}
- ok_ = havex && havey && haveunit;
- }
- if (haveunit) {
- if (unit==3) {
- x_ *= 2.54;
- y_ *= 2.54;
+ if (haveunit) {
+ if ( unit == 3 ) {
+ x_ *= 2.54;
+ y_ *= 2.54;
+ }
}
- }
- ok_ = havex && havey;
+ ok_ = havex && havey;
}
#else
@@ -249,7 +262,7 @@ void ImageResolution::readexiv(char const *) {
#include <setjmp.h>
static void irjfif_error_exit(j_common_ptr cinfo) {
- longjmp(*(jmp_buf*)cinfo->client_data, 1);
+ longjmp(*(jmp_buf*)cinfo->client_data, 1);
}
static void irjfif_emit_message(j_common_ptr, int) {
@@ -265,44 +278,52 @@ static void irjfif_reset(j_common_ptr) {
}
void ImageResolution::readjfif(char const *fn) {
- FILE *ifd = fopen(fn, "rb");
- if (!ifd)
- return;
-
- struct jpeg_decompress_struct cinfo;
- jmp_buf jbuf;
- struct jpeg_error_mgr jerr;
- bool constr = false;
+ FILE *ifd = fopen(fn, "rb");
+ if (!ifd) {
+ return;
+ }
- if (setjmp(jbuf)) {
+ struct jpeg_decompress_struct cinfo;
+ jmp_buf jbuf;
+ struct jpeg_error_mgr jerr;
+ bool constr = false;
+
+ if (setjmp(jbuf)) {
+ fclose(ifd);
+ if (constr) {
+ jpeg_destroy_decompress(&cinfo);
+ }
+ return;
+ }
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+ jerr.error_exit = &irjfif_error_exit;
+ jerr.emit_message = &irjfif_emit_message;
+ jerr.output_message = &irjfif_output_message;
+ jerr.format_message = &irjfif_format_message;
+ jerr.reset_error_mgr = &irjfif_reset;
+ cinfo.client_data = (void*)&jbuf;
+
+ constr = true;
+
+ jpeg_stdio_src(&cinfo, ifd);
+ jpeg_read_header(&cinfo, TRUE);
+
+ if (cinfo.saw_JFIF_marker) { // JFIF APP0 marker was seen
+ if ( cinfo.density_unit == 1 ) { // dots/inch
+ x_ = cinfo.X_density;
+ y_ = cinfo.Y_density;
+ ok_ = true;
+ } else if ( cinfo.density_unit == 2 ) { // dots/cm
+ x_ = cinfo.X_density * 2.54;
+ y_ = cinfo.Y_density * 2.54;
+ ok_ = true;
+ }
+ }
+ constr = false;
+ jpeg_destroy_decompress(&cinfo);
fclose(ifd);
- if (constr)
- jpeg_destroy_decompress(&cinfo);
- return;
- }
-
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_decompress(&cinfo);
- jerr.error_exit = &irjfif_error_exit;
- jerr.emit_message = &irjfif_emit_message;
- jerr.output_message = &irjfif_output_message;
- jerr.format_message = &irjfif_format_message;
- jerr.reset_error_mgr = &irjfif_reset;
- cinfo.client_data = (void*)&jbuf;
- constr = true;
-
- jpeg_stdio_src(&cinfo, ifd);
- jpeg_read_header(&cinfo, TRUE);
-
- if (cinfo.density_unit==1) {
- x_ = cinfo.X_density;
- y_ = cinfo.Y_density;
- ok_ = true;
- }
-
- constr = false;
- jpeg_destroy_decompress(&cinfo);
- fclose(ifd);
}
#else
@@ -312,7 +333,7 @@ void ImageResolution::readjfif(char const *) {
}
#endif
-
+
}
}
}