Ejemplo n.º 1
0
static gint 
get_orientation (j_decompress_ptr cinfo)
{
	/* This function looks through the meta data in the libjpeg decompress structure to
	   determine if an EXIF Orientation tag is present and if so return its value (1-8). 
	   If no EXIF Orientation tag is found 0 (zero) is returned. */

 	guint   i;              /* index into working buffer */
 	guint   orient_tag_id;  /* endianed version of orientation tag ID */
	guint   ret;            /* Return value */
 	guint   offset;        	/* de-endianed offset in various situations */
 	guint   tags;           /* number of tags in current ifd */
 	guint   type;           /* de-endianed type of tag used as index into types[] */
 	guint   count;          /* de-endianed count of elements in a tag */
        guint   tiff = 0;   	/* offset to active tiff header */
        guint   endian = 0;   	/* detected endian of data */

	jpeg_saved_marker_ptr exif_marker;  /* Location of the Exif APP1 marker */
	jpeg_saved_marker_ptr cmarker;	    /* Location to check for Exif APP1 marker */

	/* check for Exif marker (also called the APP1 marker) */
	exif_marker = NULL;
	cmarker = cinfo->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;
	}
	  
	/* Did we find the Exif APP1 marker? */
	if (exif_marker == NULL)
		return 0;

	/* Do we have enough data? */
	if (exif_marker->data_length < 32)
		return 0;

        /* Check for TIFF header and catch endianess */
 	i = 0;

	/* Just skip data until TIFF header - it should be within 16 bytes from marker start.
	   Normal structure relative to APP1 marker -
		0x0000: APP1 marker entry = 2 bytes
	   	0x0002: APP1 length entry = 2 bytes
		0x0004: Exif Identifier entry = 6 bytes
		0x000A: Start of TIFF header (Byte order entry) - 4 bytes  
		    	- This is what we look for, to determine endianess.
		0x000E: 0th IFD offset pointer - 4 bytes

		exif_marker->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.
 	*/
		    
 	while (i < 16) {
 
 		/* Little endian TIFF header */
 		if (memcmp (&exif_marker->data[i], leth, 4) == 0){ 
 			endian = G_LITTLE_ENDIAN;
                }
 
 		/* Big endian TIFF header */
 		else if (memcmp (&exif_marker->data[i], beth, 4) == 0){ 
 			endian = G_BIG_ENDIAN;
                }
 
 		/* Keep looking through buffer */
 		else {
 			i++;
 			continue;
 		}
 		/* We have found either big or little endian TIFF header */
 		tiff = i;
 		break;
        }

 	/* So did we find a TIFF header or did we just hit end of buffer? */
 	if (tiff == 0) 
		return 0;
 
        /* Endian the orientation tag ID, to locate it more easily */
        orient_tag_id = ENDIAN16_IT(0x112);
 
        /* Read out the offset pointer to IFD0 */
        offset  = de_get32(&exif_marker->data[i] + 4, endian);
 	i       = i + offset;

	/* Check that we still are within the buffer and can read the tag count */
	if ((i + 2) > exif_marker->data_length)
		return 0;

	/* Find out how many tags we have in IFD0. As per the TIFF spec, the first
	   two bytes of the IFD contain a count of the number of tags. */
	tags    = de_get16(&exif_marker->data[i], endian);
	i       = i + 2;

	/* Check that we still have enough data for all tags to check. The tags
	   are listed in consecutive 12-byte blocks. The tag ID, type, size, and
	   a pointer to the actual value, are packed into these 12 byte entries. */
	if ((i + tags * 12) > exif_marker->data_length)
		return 0;

	/* Check through IFD0 for tags of interest */
	while (tags--){
		type   = de_get16(&exif_marker->data[i + 2], endian);
		count  = de_get32(&exif_marker->data[i + 4], endian);

		/* Is this the orientation tag? */
		if (memcmp (&exif_marker->data[i], (char *) &orient_tag_id, 2) == 0){ 
 
			/* Check that type and count fields are OK. The orientation field 
			   will consist of a single (count=1) 2-byte integer (type=3). */
			if (type != 3 || count != 1) return 0;

			/* Return the orientation value. Within the 12-byte block, the
			   pointer to the actual data is at offset 8. */
			ret =  de_get16(&exif_marker->data[i + 8], endian);
			return ret <= 8 ? ret : 0;
		}
		/* move the pointer to the next 12-byte tag field. */
		i = i + 12;
	}

	return 0; /* No EXIF Orientation tag found */
}
Ejemplo n.º 2
0
static gboolean
jpeg_parse_exif_app1 (JpegExifContext *context, jpeg_saved_marker_ptr marker)
{
	guint i;
	guint ret = FALSE;
	guint offset;
	guint tags;	   /* number of tags in current ifd */
	guint endian = 0;	/* detected endian of data */
	const char leth[]  = {0x49, 0x49, 0x2a, 0x00};	// Little endian TIFF header
	const char beth[]  = {0x4d, 0x4d, 0x00, 0x2a};	// Big endian TIFF header

	/* do we have enough data? */
	if (marker->data_length < 4)
		goto out;

	/* unique identification string */
	if (memcmp (marker->data, "Exif", 4) != 0)
		goto out;

	/* do we have enough data? */
	if (marker->data_length < 32)
		goto out;

	/* Just skip data until TIFF header - it should be within 16 bytes from marker start.
	   Normal structure relative to APP1 marker -
		0x0000: APP1 marker entry = 2 bytes
		0x0002: APP1 length entry = 2 bytes
		0x0004: Exif Identifier entry = 6 bytes
		0x000A: Start of TIFF header (Byte order entry) - 4 bytes
			- This is what we look for, to determine endianess.
		0x000E: 0th IFD offset pointer - 4 bytes

		marker->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.
	*/

	for (i=0; i<16; i++) {
		/* little endian TIFF header */
		if (memcmp (&marker->data[i], leth, 4) == 0) {
			endian = G_LITTLE_ENDIAN;
			ret = TRUE;
			break;
		}

		/* big endian TIFF header */
		if (memcmp (&marker->data[i], beth, 4) == 0) {
			endian = G_BIG_ENDIAN;
			ret = TRUE;
			break;
		}
	}

	/* could not find header */
	if (!ret)
		goto out;

	/* read out the offset pointer to IFD0 */
	offset  = de_get32(&marker->data[i] + 4, endian);
	i = i + offset;

	/* check that we still are within the buffer and can read the tag count */
	if ((i + 2) > marker->data_length) {
		ret = FALSE;
		goto out;
	}

	/* find out how many tags we have in IFD0. As per the TIFF spec, the first
	   two bytes of the IFD contain a count of the number of tags. */
	tags = de_get16(&marker->data[i], endian);
	i = i + 2;

	/* check that we still have enough data for all tags to check. The tags
	   are listed in consecutive 12-byte blocks. The tag ID, type, size, and
	   a pointer to the actual value, are packed into these 12 byte entries. */
	if ((i + tags * 12) > marker->data_length) {
		ret = FALSE;
		goto out;
	}

	/* check through IFD0 for tags */
	while (tags--){
		guint tag   = de_get16(&marker->data[i + 0], endian);
		guint type  = de_get16(&marker->data[i + 2], endian);
		guint count = de_get32(&marker->data[i + 4], endian);
		/* values of types small enough to fit are stored directly in the (first) bytes of the Value Offset field */
		guint short_value = de_get16(&marker->data[i + 8], endian);

		/* orientation tag? */
		if (tag == 0x112){

			/* The orientation field should consist of a single 2-byte integer */
			if (type != 0x3 || count != 1)
				continue;

			/* get the orientation value */
			context->orientation = short_value <= 8 ? short_value : 0;
		}
		/* move the pointer to the next 12-byte tag field. */
		i = i + 12;
	}

out:
	return ret;
}