Example #1
0
static void format_debug_tiff_entry(guchar *data, const guint len, guint offset,
				    ExifByteOrder bo, gint level)
{
	guint tag;
	guint type;
	guint count;
	guint segment;
	guint seg_len;

	tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo);
	type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo);
	count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo);

	seg_len = ExifFormatList[type].size * count;
	if (seg_len > 4)
		{
		segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo);
		if (segment + seg_len > len) return;
		}
	else
		{
		segment = offset + EXIF_TIFD_OFFSET_DATA;
		}

	log_printf("%*stag:0x%04X (%05d), type:%2d %9s, len:%6d [%02X %02X %02X %02X] @ offset:%d\n",
		level, "", tag, tag, type,
		(type < EXIF_FORMAT_COUNT) ? ExifFormatList[type].short_name : "???", count,
		data[segment], data[segment + 1], data[segment + 2], data[segment + 3], segment);

	if (tag == 0x8769 || tag == 0x14a)
		{
		gint i;

		log_printf("%*s~~~ found %s table\n", level, "", (tag == 0x14a) ? "subIFD" : "EXIF" );

		for (i = 0; i < count; i++)
			{
			guint subset;

			subset = exif_byte_get_int32(data + segment + i * 4, bo);
			format_debug_tiff_table(data, len, subset, bo, level + 1);
			}
		}
	else if (tag == 0x8773 && type == EXIF_FORMAT_UNDEFINED)
		{
		log_printf("%*s~~~ found ICC color profile at offset %d, length %d\n", level, "", segment, seg_len);
		}
	else if (tag == 0x201 && (type == EXIF_FORMAT_LONG_UNSIGNED || type == EXIF_FORMAT_LONG))
		{
		guint subset = exif_byte_get_int32(data + segment, bo);
		log_printf("%*s~~~ found jpeg data at offset %d\n", level, "", subset);
		}
	else if (tag == 0x202 && (type == EXIF_FORMAT_LONG_UNSIGNED || type == EXIF_FORMAT_LONG))
		{
		guint subset = exif_byte_get_int32(data + segment, bo);
		log_printf("%*s~~~ found jpeg data length of %d\n", level, "", subset);
		}
}
Example #2
0
static void nikon_tiff_entry(guchar *data, const guint len, guint offset, ExifByteOrder bo,
			     gint level,
			     guint *image_offset, guint *image_length, guint *jpeg_start, guint *jpeg_len)
{
	guint tag;
	guint type;
	guint count;
	guint segment;
	guint seg_len;

	tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo);
	type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo);
	count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo);

	/* so far, we only care about tags with type long */
	if (type != EXIF_FORMAT_LONG_UNSIGNED && type != EXIF_FORMAT_LONG) return;

	seg_len = ExifFormatList[type].size * count;
	if (seg_len > 4)
		{
		segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo);
		if (segment + seg_len > len) return;
		}
	else
		{
		segment = offset + EXIF_TIFD_OFFSET_DATA;
		}

	if (tag == 0x14a)
		{
		/* sub IFD table */
		guint i;

		for (i = 0; i < count; i++)
			{
			guint subset;

			subset = exif_byte_get_int32(data + segment + i * 4, bo);
			nikon_tiff_table(data, len, subset, bo, level + 1, image_offset, image_length);
			}

		}
	else if (tag == 0x201)
		{
		/* jpeg data start offset */
		*jpeg_start = exif_byte_get_int32(data + segment, bo);
		}
	else if (tag == 0x202)
		{
		/* jpeg data length */
		*jpeg_len = exif_byte_get_int32(data + segment, bo);
		}
}
Example #3
0
static guint tiff_table(guchar *data, const guint len, guint offset, ExifByteOrder bo,
			guint tag, ExifFormatType type,
			guint *result_offset, guint *result_count)
{
	guint count;
	guint i;

	if (len < offset + 2) return 0;
	if (type > EXIF_FORMAT_COUNT) return 0;

	count = exif_byte_get_int16(data + offset, bo);
	offset += 2;
	if (len < offset + count * 12 + 4) return 0;

	for (i = 0; i < count; i++)
		{
		guint segment;

		segment = offset + i * 12;
		if (exif_byte_get_int16(data + segment, bo) == tag &&
		    exif_byte_get_int16(data + segment + 2, bo) == type)
			{
			guint chunk_count;
			guint chunk_offset;
			guint chunk_length;

			chunk_count = exif_byte_get_int32(data + segment + 4, bo);
			chunk_length = ExifFormatList[type].size * chunk_count;

			if (chunk_length > 4)
				{
				chunk_offset = exif_byte_get_int32(data + segment + 8, bo);
				}
			else
				{
				chunk_offset = segment + 8;
				}

			if (chunk_offset + chunk_length <= len)
				{
				*result_offset = chunk_offset;
				*result_count = chunk_count;
				}

			return 0;
			}
		}

	return exif_byte_get_int32(data + offset + count * 12, bo);
}
Example #4
0
static guint format_debug_tiff_table(guchar *data, const guint len, guint offset,
				     ExifByteOrder bo, gint level)
{
	guint count;
	guint i;

	if (level > EXIF_TIFF_MAX_LEVELS) return 0;

	if (len < offset + 2) return FALSE;

	count = exif_byte_get_int16(data + offset, bo);
	offset += 2;
	if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;

	log_printf("%*s== tiff table #%d has %d entries ==\n", level, "", level, count);

	for (i = 0; i < count; i++)
		{
		format_debug_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level);
		}

	log_printf("%*s----------- end of #%d ------------\n", level, "", level);

	return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo);
}
gint format_olympus_raw(unsigned char *data, const guint len,
			guint *image_offset, guint *exif_offset)
{
	guint i_off = 0;
	guint e_off = 0;
	guint offset;
	gint level;

	if (len < 8) return FALSE;

	/* these are in tiff file format with a different magick header */
	if (memcmp(data, "IIR", 3) != 0) return FALSE;

	offset = exif_byte_get_int32(data + 4, EXIF_BYTE_ORDER_INTEL);

	level = 0;
	while (offset && level < EXIF_TIFF_MAX_LEVELS)
		{
		offset = olympus_tiff_table(data, len, offset, EXIF_BYTE_ORDER_INTEL, 0, &i_off, &e_off);
		level++;
		}

	if (i_off != 0 || e_off != 0)
		{
		if (image_offset) *image_offset = i_off;
		if (exif_offset) *exif_offset = e_off;
		return TRUE;
		}

	return FALSE;
}
Example #6
0
static guint nikon_tiff_table(guchar *data, const guint len, guint offset, ExifByteOrder bo,
			      gint level,
			      guint *image_offset, guint *image_length)
{
	guint count;
	guint i;
	guint jpeg_start = 0;
	guint jpeg_len = 0;

	/* limit damage from infinite loops */
	if (level > EXIF_TIFF_MAX_LEVELS) return 0;

	if (len < offset + 2) return FALSE;

	count = exif_byte_get_int16(data + offset, bo);
	offset += 2;
	if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;

	for (i = 0; i < count; i++)
		{
		nikon_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level,
				 image_offset, image_length, &jpeg_start, &jpeg_len);
		}

	if (jpeg_start > 0 &&
	    jpeg_len > *image_length)
		{
		*image_offset = jpeg_start;
		*image_length = jpeg_len;
		}

	return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo);
}
Example #7
0
gint format_fuji_raw(unsigned char *data, const guint len,
		     guint *image_offset, guint *exif_offset)
{
	guint io;
	guint eo;

	if (len < 128 ||
	    memcmp(data, "FUJIFILM", 8) != 0)
		{
		return FALSE;
		}

	/* offset to jpeg is embedded at bytes 84-87 */
	io = exif_byte_get_int32(data + 84, EXIF_BYTE_ORDER_MOTOROLA);
	if (io + 4 > len) return FALSE;

	/* verify jpeg marker */
	if (memcmp(data + io, "\xff\xd8\xff\xe1", 4) != 0)
		{
		return FALSE;
		}

	/* Exif is stored in the jpeg, so use the same offset */
	eo=io;

	if (image_offset) *image_offset = io;
	if (exif_offset) *exif_offset = eo;

	return TRUE;
}
Example #8
0
gint format_fuji_makernote(ExifData *exif, unsigned char *tiff, guint offset,
			   guint size, ExifByteOrder bo)
{
	unsigned char *data;
	guint ifdstart;

	if (offset + 8 + 4 >= size) return FALSE;

	data = tiff + offset;

	/* Fuji tag format starts with "FUJIFILM",
	 * followed by 4 bytes indicating offset to IFD directory using Fuji tags,
	 * byte order is always little endian (II).
	 */
	if (memcmp(data, "FUJIFILM", 8) != 0) return FALSE;

	ifdstart = exif_byte_get_int32(data + 8, EXIF_BYTE_ORDER_INTEL);
	if (offset + ifdstart >= size) return FALSE;

	if (exif_parse_IFD_table(exif, tiff + offset, ifdstart, size - offset,
				 EXIF_BYTE_ORDER_INTEL, 0, FujiExifMarkersList) != 0)
		{
		return FALSE;
		}

	return TRUE;
}
static void olympus_tiff_entry(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
			       gint level,
			       guint *image_offset, guint *exif_offset)
{
	guint tag;
	guint type;
	guint count;
	guint segment;
	guint seg_len;

	tag = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_TAG, bo);
	type = exif_byte_get_int16(data + offset + EXIF_TIFD_OFFSET_FORMAT, bo);
	count = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_COUNT, bo);

	/* so far, we only care about tags with type long */
	if (type != EXIF_FORMAT_LONG_UNSIGNED && type != EXIF_FORMAT_LONG) return;

	seg_len = ExifFormatList[type].size * count;
	if (seg_len > 4)
		{
		segment = exif_byte_get_int32(data + offset + EXIF_TIFD_OFFSET_DATA, bo);
		if (segment + seg_len > len) return;
		}
	else
		{
		segment = offset + EXIF_TIFD_OFFSET_DATA;
		}

	if (tag == 0x201)
		{
		/* start of embedded jpeg, not all olympus cameras embed a jpeg */
		*image_offset = exif_byte_get_int32(data + segment, bo);
		}

	if (tag == 0x8769)
		{
		/* This is the Exif info */
		*exif_offset = exif_byte_get_int32(data + segment, bo);
		}
}
Example #10
0
static gboolean format_tiff_find_tag_data(guchar *data, const guint len,
				          guint tag, ExifFormatType type,
				          guint *result_offset, guint *result_count)
{
	ExifByteOrder bo;
	guint offset;

	if (len < 8) return FALSE;

	if (memcmp(data, "II", 2) == 0)
		{
		bo = EXIF_BYTE_ORDER_INTEL;
		}
	else if (memcmp(data, "MM", 2) == 0)
		{
		bo = EXIF_BYTE_ORDER_MOTOROLA;
		}
	else
		{
		return FALSE;
		}

	if (exif_byte_get_int16(data + 2, bo) != 0x002A)
		{
		return FALSE;
		}

	offset = exif_byte_get_int32(data + 4, bo);

	while (offset != 0)
		{
		guint ro = 0;
		guint rc = 0;

		offset = tiff_table(data, len, offset, bo, tag, type, &ro, &rc);
		if (ro != 0)
			{
			*result_offset = ro;
			*result_count = rc;
			return TRUE;
			}
		}

	return FALSE;
}
Example #11
0
gboolean format_debug_tiff_raw(guchar *data, const guint len,
			       guint *image_offset, guint *exif_offset)
{
	ExifByteOrder bo;
	gint level;
	guint offset;

	if (len < 8) return FALSE;

	/* for debugging, we are more relaxed as to magic header */
	if (memcmp(data, "II", 2) == 0)
		{
		bo = EXIF_BYTE_ORDER_INTEL;
		}
	else if (memcmp(data, "MM", 2) == 0)
		{
		bo = EXIF_BYTE_ORDER_MOTOROLA;
		}
	else
		{
		return FALSE;
		}

	log_printf("*** debug parsing tiff\n");

	offset = exif_byte_get_int32(data + 4, bo);
	level = 0;
	while (offset && level < EXIF_TIFF_MAX_LEVELS)
		{
		offset = format_debug_tiff_table(data, len, offset, bo, 0);
		level++;
		}

	log_printf("*** end\n");

	/* we are debugging, not trying to return any data */
	return FALSE;
}
Example #12
0
static guint olympus_tiff_table(unsigned char *data, const guint len, guint offset, ExifByteOrder bo,
				gint level,
				guint *image_offset, guint *exif_offset)
{
	guint count;
	guint i;

	if (level > EXIF_TIFF_MAX_LEVELS) return 0;

	if (len < offset + 2) return FALSE;

	count = exif_byte_get_int16(data + offset, bo);
	offset += 2;
	if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;

	for (i = 0; i < count; i++)
		{
		olympus_tiff_entry(data, len, offset + i * EXIF_TIFD_SIZE, bo, level,
				   image_offset, exif_offset);
		}

	return exif_byte_get_int32(data + offset + count * EXIF_TIFD_SIZE, bo);
}