diff --git a/src/osgPlugins/jpeg/CMakeLists.txt b/src/osgPlugins/jpeg/CMakeLists.txt index c3021cbe5..7117713a0 100644 --- a/src/osgPlugins/jpeg/CMakeLists.txt +++ b/src/osgPlugins/jpeg/CMakeLists.txt @@ -1,6 +1,10 @@ INCLUDE_DIRECTORIES( ${JPEG_INCLUDE_DIR} ) -SET(TARGET_SRC ReaderWriterJPEG.cpp ) +SET(TARGET_SRC + EXIF_Orientation.cpp + ReaderWriterJPEG.cpp +) + SET(TARGET_LIBRARIES_VARS JPEG_LIBRARY ) #### end var setup ### SETUP_PLUGIN(jpeg) diff --git a/src/osgPlugins/jpeg/EXIF_Orientation.cpp b/src/osgPlugins/jpeg/EXIF_Orientation.cpp new file mode 100644 index 000000000..e0c25ae5b --- /dev/null +++ b/src/osgPlugins/jpeg/EXIF_Orientation.cpp @@ -0,0 +1,182 @@ +#include "EXIF_Orientation.h" + +#include +#include + +#include +#include + +#define EXIF_IDENT_STRING "Exif\000\000" + +static unsigned short de_get16(void *ptr, bool byteSwap) +{ + unsigned short val; + + memcpy(&val, ptr, sizeof(val)); + if (byteSwap) osg::swapBytes(val); + + return val; +} + +static unsigned int de_get32(void *ptr, bool byteSwap) +{ + unsigned int val; + + memcpy(&val, ptr, sizeof(val)); + if (byteSwap) osg::swapBytes(val); + + return val; +} + +int EXIF_Orientation (j_decompress_ptr cinfo) +{ + OSG_INFO<<"get_orientation()"<marker_list; + while (cmarker) + { + if (cmarker->marker == EXIF_JPEG_MARKER) + { + /* The Exif APP1 marker should contain a unique + identification string ("Exif\0\0"). Check for it. */ + if (!memcmp (cmarker->data, EXIF_IDENT_STRING, 6)) + { + exif_marker = cmarker; + } + } + cmarker = cmarker->next; + } + + if (exif_marker==NULL) + { + OSG_INFO<<"exif_marker not found "<data_length < 32) + { + OSG_INFO<<"exif_marker too short : "<data_length<data points to the first data after the APP1 marker + and length entries, which is the exif identification string. + The TIFF header should thus normally be found at i=6, below, + and the pointer to IFD0 will be at 6+4 = 10. + */ + + + /* Check for TIFF header and catch endianess */ + unsigned int i = 0; + for(i=0; i < 16; ++i) + { + /* Little endian TIFF header */ + if (memcmp (&exif_marker->data[i], leth, 4) == 0) + { + tiffHeaderEndian = osg::LittleEndian; + break; + } + /* Big endian TIFF header */ + else if (memcmp (&exif_marker->data[i], beth, 4) == 0) + { + tiffHeaderEndian = osg::BigEndian; + break; + } + } + + /* So did we find a TIFF header or did we just hit end of buffer? */ + if (i >= 16) + { + OSG_INFO<<"Could not find TIFF header"<data[i], swapBytes); + unsigned int type = de_get16(&exif_marker->data[i + 2], swapBytes); + unsigned int count = de_get32(&exif_marker->data[i + 4], swapBytes); + + OSG_INFO<<" tag=0x"< + +extern "C" +{ + #include + #include "jerror.h" +} + +#define EXIF_JPEG_MARKER JPEG_APP0+1 + +extern int EXIF_Orientation (j_decompress_ptr cinfo); + +#endif diff --git a/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp b/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp index c07e7b969..74be90cb8 100644 --- a/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp +++ b/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp @@ -48,13 +48,7 @@ * */ -#include - -extern "C" -{ - #include - #include "jerror.h" -} +#include "EXIF_Orientation.h" #include #include @@ -467,11 +461,11 @@ copyScanline(unsigned char *currPtr, unsigned char *from, int cnt) return currPtr; } -unsigned char * -simage_jpeg_load(std::istream& fin, -int *width_ret, -int *height_ret, -int *numComponents_ret) +unsigned char* simage_jpeg_load(std::istream& fin, + int *width_ret, + int *height_ret, + int *numComponents_ret, + unsigned int* exif_orientation) { int width; int height; @@ -535,8 +529,12 @@ int *numComponents_ret) //jpeg_stdio_src(&cinfo, infile); jpeg_istream_src(&cinfo,&fin); + + /* Step 3: read file parameters with jpeg_read_header() */ + jpeg_save_markers (&cinfo, EXIF_JPEG_MARKER, 0xffff); + (void) jpeg_read_header(&cinfo, TRUE); /* We can ignore the return value from jpeg_read_header since * (a) suspension is not possible with the stdio data source, and @@ -544,6 +542,14 @@ int *numComponents_ret) * See libjpeg.doc for more info. */ + /* check for orientation tag */ + *exif_orientation = EXIF_Orientation (&cinfo); + if (*exif_orientation!=0) + { + OSG_INFO<<"We have an EXIF_Orientation "<0) + { + // guide for meaning of exif_orientation provided by webpage: http://sylvana.net/jpegcrop/exif_orientation.html + switch(exif_orientation) + { + case(1): OSG_NOTICE<<"EXIF_Orientation 1 (top, left side), No need to rotate image. "<