static void exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d, unsigned int ds, ExifLong offset, ExifLong size) { if ((ds < offset + size) || (offset > ds)) { exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail offset (%u) or size (%u).", offset, size); return; } if (data->data) exif_mem_free (data->priv->mem, data->data); data->size = size; data->data = exif_data_alloc (data, data->size); if (!data->data) return; memcpy (data->data, d + offset, data->size); }
void exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds) { if (ds) *ds = 0; /* This means something went wrong */ if (!data || !d || !ds) return; /* Header */ *ds = 14; *d = exif_data_alloc (data, *ds); if (!*d) { *ds = 0; return; } memcpy (*d, ExifHeader, 6); /* Order (offset 6) */ if (data->priv->order == EXIF_BYTE_ORDER_INTEL) { memcpy (*d + 6, "II", 2); } else { memcpy (*d + 6, "MM", 2); } /* Fixed value (2 bytes, offset 8) */ exif_set_short (*d + 8, data->priv->order, 0x002a); /* * IFD 0 offset (4 bytes, offset 10). * We will start 8 bytes after the * EXIF header (2 bytes for order, another 2 for the test, and * 4 bytes for the IFD 0 offset make 8 bytes together). */ exif_set_long (*d + 10, data->priv->order, 8); /* Now save IFD 0. IFD 1 will be saved automatically. */ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Saving IFDs..."); exif_data_save_data_content (data, data->ifd[EXIF_IFD_0], d, ds, *ds - 6); exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Saved %i byte(s) EXIF data.", *ds); }
static void exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d, unsigned int ds, ExifLong o, ExifLong s) { /* Sanity checks */ if ((o + s < o) || (o + s < s) || (o + s > ds) || (o > ds)) { exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail offset (%u) or size (%u).", o, s); return; } if (data->data) exif_mem_free (data->priv->mem, data->data); if (!(data->data = exif_data_alloc (data, s))) { EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", s); data->size = 0; return; } data->size = s; memcpy (data->data, d + o, s); }
static int exif_data_load_data_entry (ExifData *data, ExifEntry *entry, const unsigned char *d, unsigned int size, unsigned int offset) { unsigned int s, doff; entry->tag = exif_get_short (d + offset + 0, data->priv->order); entry->format = exif_get_short (d + offset + 2, data->priv->order); entry->components = exif_get_long (d + offset + 4, data->priv->order); /* FIXME: should use exif_tag_get_name_in_ifd here but entry->parent * has not been set yet */ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Loading entry 0x%x ('%s')...", entry->tag, exif_tag_get_name (entry->tag)); /* {0,1,2,4,8} x { 0x00000000 .. 0xffffffff } * -> { 0x000000000 .. 0x7fffffff8 } */ s = exif_format_get_size(entry->format) * entry->components; if ((s < entry->components) || (s == 0)){ return 0; } /* * Size? If bigger than 4 bytes, the actual data is not * in the entry but somewhere else (offset). */ if (s > 4) doff = exif_get_long (d + offset + 8, data->priv->order); else doff = offset + 8; /* Sanity checks */ if ((doff + s < doff) || (doff + s < s) || (doff + s > size)) { exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Tag data past end of buffer (%u > %u)", doff+s, size); return 0; } entry->data = exif_data_alloc (data, s); if (entry->data) { entry->size = s; memcpy (entry->data, d + doff, s); } else { /* FIXME: What do our callers do if (entry->data == NULL)? */ EXIF_LOG_NO_MEMORY(data->priv->log, "ExifData", s); } /* If this is the MakerNote, remember the offset */ if (entry->tag == EXIF_TAG_MAKER_NOTE) { if (!entry->data) { exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "MakerNote found with empty data"); } else if (entry->size > 6) { exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "MakerNote found (%02x %02x %02x %02x " "%02x %02x %02x...).", entry->data[0], entry->data[1], entry->data[2], entry->data[3], entry->data[4], entry->data[5], entry->data[6]); } data->priv->offset_mnote = doff; } return 1; }