void
jpeg_data_load_data (JPEGData *data, const unsigned char *d,
		     unsigned int size)
{
	unsigned int i, o, len;
	JPEGSection *s;
	JPEGMarker marker;

	if (!data) return;
	if (!d) return;

	for (o = 0; o < size;) {

		/*
		 * JPEG sections start with 0xff. The first byte that is
		 * not 0xff is a marker (hopefully).
		 */
		for (i = 0; i < MIN(7, size - o); i++)
			if (d[o + i] != 0xff)
				break;
		if ((i >= size - o) || !JPEG_IS_MARKER (d[o + i])) {
			exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "jpeg-data",
					_("Data does not follow JPEG specification."));
			return;
		}
		marker = d[o + i];

		/* Append this section */
		jpeg_data_append_section (data);
		if (!data->count) return;
		s = &data->sections[data->count - 1];
		s->marker = marker;
		o += i + 1;

		switch (s->marker) {
		case JPEG_MARKER_SOI:
		case JPEG_MARKER_EOI:
			break;
		default:

			/* Read the length of the section */
			if (2 > size - o) { o = size; break; }
			len = ((d[o] << 8) | d[o + 1]) - 2;
			if (len > size) { o = size; break; }
			o += 2;
			if (len > size - o) { o = size; break; }

			switch (s->marker) {
			case JPEG_MARKER_APP1:
            /* Changed to add the EXIF_LOG feature.
               2012.04.05 - Samsung Electronics */
				/*s->content.app1 = exif_data_new_from_data (
							d + o - 4, len + 4); */
				s->content.app1 = exif_data_new();
                exif_data_log(s->content.app1, data->priv->log);
            	exif_data_load_data (s->content.app1, d + o - 4, len + 4);
				break;
			default:
				s->content.generic.data =
						malloc (sizeof (char) * len);
				if (!s->content.generic.data) {
					EXIF_LOG_NO_MEMORY (data->priv->log, "jpeg-data", sizeof (char) * len);
					return;
				}
				s->content.generic.size = len;
				memcpy (s->content.generic.data, &d[o], len);

				/* In case of SOS, image data will follow. */
				if (s->marker == JPEG_MARKER_SOS) {
					data->size = size - o - len;
					if (data->size >= 2) {
						/* -2 means 'take all but the last 2 bytes which are
						   hoped to be JPEG_MARKER_EOI */
						data->size -= 2;
						if (d[o + len + data->size] != 0xFF) {
							/* A truncated file (i.e. w/o JPEG_MARKER_EOI at the end).
							   Instead of trying to use the last two bytes as marker,
							   touching memory beyond allocated memory and posssibly saving
							   back screwed file, we rather take the rest of the file. */
							data->size += 2;
						}
					}
					data->data = malloc (
						sizeof (char) * data->size);
					if (!data->data) {
						EXIF_LOG_NO_MEMORY (data->priv->log, "jpeg-data", sizeof (char) * data->size);
						data->size = 0;
						return;
					}
					memcpy (data->data, d + o + len,
						data->size);
					o += data->size;
				}
				break;
			}
			o += len;
			break;
		}
	}
}
Пример #2
0
void
jpeg_data_load_data (JPEGData *data, const unsigned char *d,
		     unsigned int size)
{
	unsigned int i, o, len;
	JPEGSection *s;
	JPEGMarker marker;

	if (!data)
		return;
	if (!d)
		return;

#ifdef DEBUG
	printf ("Parsing %i bytes...\n", size);
#endif

	for (o = 0; o < size;) {

		/*
		 * JPEG sections start with 0xff. The first byte that is
		 * not 0xff is a marker (hopefully).
		 */
		for (i = 0; i < 7; i++)
			if (d[o + i] != 0xff)
				break;
		if (!JPEG_IS_MARKER (d[o + i]))
			return;
		marker = d[o + i];

#ifdef DEBUG
		printf ("Found marker 0x%x ('%s') at %i.\n", marker,
			jpeg_marker_get_name (marker), o + i);
#endif

		/* Append this section */
		jpeg_data_append_section (data);
		s = &data->sections[data->count - 1];
		s->marker = marker;
		s->content.generic.data = NULL;
		o += i + 1;

		switch (s->marker) {
		case JPEG_MARKER_SOI:
		case JPEG_MARKER_EOI:
			break;
		default:

			/* Read the length of the section */
			len = ((d[o] << 8) | d[o + 1]) - 2;
			if (len > size) { o = size; break; }
			o += 2;
			if (o + len > size) { o = size; break; }

			switch (s->marker) {
			case JPEG_MARKER_APP1:
				s->content.app1 = exif_data_new_from_data (
							d + o - 4, len + 4);
				break;
			default:
				s->content.generic.size = len;
				s->content.generic.data =
						malloc (sizeof (char) * len);
				memcpy (s->content.generic.data, &d[o], len);

				/* In case of SOS, image data will follow. */
				if (s->marker == JPEG_MARKER_SOS) {
					data->size = size - 2 - o - len;
					data->data = malloc (
						sizeof (char) * data->size);
					memcpy (data->data, d + o + len,
						data->size);
					o += data->size;
				}
				break;
			}
			o += len;
			break;
		}
	}
}