00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022 #include <string.h>
00023
00024
00025 #include <config.h>
00026 #include <libexif/exif-byte-order.h>
00027 #include <libexif/exif-utils.h>
00028
00029 #include "exif-mnote-data-fuji.h"
00030
00031 struct _MNoteFujiDataPrivate {
00032 ExifByteOrder order;
00033 };
00034
00035 static void
00036 exif_mnote_data_fuji_clear (ExifMnoteDataFuji *n)
00037 {
00038 ExifMnoteData *d = (ExifMnoteData *) n;
00039 unsigned int i;
00040
00041 if (!n) return;
00042
00043 if (n->entries) {
00044 for (i = 0; i < n->count; i++)
00045 if (n->entries[i].data) {
00046 exif_mem_free (d->mem, n->entries[i].data);
00047 n->entries[i].data = NULL;
00048 }
00049 exif_mem_free (d->mem, n->entries);
00050 n->entries = NULL;
00051 n->count = 0;
00052 }
00053 }
00054
00055 static void
00056 exif_mnote_data_fuji_free (ExifMnoteData *n)
00057 {
00058 if (!n) return;
00059
00060 exif_mnote_data_fuji_clear ((ExifMnoteDataFuji *) n);
00061 }
00062
00063 static char *
00064 exif_mnote_data_fuji_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
00065 {
00066 ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
00067
00068 if (!d || !val) return NULL;
00069 if (i > n->count -1) return NULL;
00070
00071
00072
00073
00074
00075 return mnote_fuji_entry_get_value (&n->entries[i], val, maxlen);
00076 }
00077
00078 static void
00079 exif_mnote_data_fuji_save (ExifMnoteData *ne, unsigned char **buf,
00080 unsigned int *buf_size)
00081 {
00082 ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) ne;
00083 size_t i, o, s, doff;
00084 unsigned char *t;
00085 size_t ts;
00086
00087 if (!n || !buf || !buf_size) return;
00088
00089
00090
00091
00092
00093 *buf_size = 8 + 4 + 2 + n->count * 12 + 4;
00094 *buf = exif_mem_alloc (ne->mem, *buf_size);
00095 if (!*buf) {
00096 *buf_size = 0;
00097 return;
00098 }
00099
00100
00101
00102
00103
00104 memcpy (*buf, "FUJIFILM", 8);
00105 exif_set_long (*buf + 8, n->order, 12);
00106
00107
00108 exif_set_short (*buf + 8 + 4, n->order, (ExifShort) n->count);
00109
00110
00111 for (i = 0; i < n->count; i++) {
00112 o = 8 + 4 + 2 + i * 12;
00113 exif_set_short (*buf + o + 0, n->order, (ExifShort) n->entries[i].tag);
00114 exif_set_short (*buf + o + 2, n->order, (ExifShort) n->entries[i].format);
00115 exif_set_long (*buf + o + 4, n->order, n->entries[i].components);
00116 o += 8;
00117 s = exif_format_get_size (n->entries[i].format) *
00118 n->entries[i].components;
00119 if (s > 65536) {
00120
00121
00122
00123 continue;
00124 }
00125 if (s > 4) {
00126 ts = *buf_size + s;
00127
00128
00129 if (s & 1) ts += 1;
00130 t = exif_mem_realloc (ne->mem, *buf, ts);
00131 if (!t) {
00132 return;
00133 }
00134 *buf = t;
00135 *buf_size = ts;
00136 doff = *buf_size - s;
00137 if (s & 1) { doff--; *(*buf + *buf_size - 1) = '\0'; }
00138 exif_set_long (*buf + o, n->order, doff);
00139 } else
00140 doff = o;
00141
00142
00143
00144
00145
00146 if (!n->entries[i].data) memset (*buf + doff, 0, s);
00147 else memcpy (*buf + doff, n->entries[i].data, s);
00148 }
00149 }
00150
00151 static void
00152 exif_mnote_data_fuji_load (ExifMnoteData *en,
00153 const unsigned char *buf, unsigned int buf_size)
00154 {
00155 ExifMnoteDataFuji *n = (ExifMnoteDataFuji*) en;
00156 ExifLong c;
00157 size_t i, tcount, o, datao;
00158
00159 if (!n || !buf || !buf_size) {
00160 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00161 "ExifMnoteDataFuji", "Short MakerNote");
00162 return;
00163 }
00164 datao = 6 + n->offset;
00165 if ((datao + 12 < datao) || (datao + 12 < 12) || (datao + 12 > buf_size)) {
00166 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00167 "ExifMnoteDataFuji", "Short MakerNote");
00168 return;
00169 }
00170
00171 n->order = EXIF_BYTE_ORDER_INTEL;
00172 datao += exif_get_long (buf + datao + 8, EXIF_BYTE_ORDER_INTEL);
00173 if ((datao + 2 < datao) || (datao + 2 < 2) ||
00174 (datao + 2 > buf_size)) {
00175 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00176 "ExifMnoteDataFuji", "Short MakerNote");
00177 return;
00178 }
00179
00180
00181 c = exif_get_short (buf + datao, EXIF_BYTE_ORDER_INTEL);
00182 datao += 2;
00183
00184
00185 exif_mnote_data_fuji_clear (n);
00186
00187
00188 n->entries = exif_mem_alloc (en->mem, sizeof (MnoteFujiEntry) * c);
00189 if (!n->entries) {
00190 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataFuji", sizeof (MnoteFujiEntry) * c);
00191 return;
00192 }
00193
00194
00195 tcount = 0;
00196 for (i = c, o = datao; i; --i, o += 12) {
00197 size_t s;
00198 if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
00199 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00200 "ExifMnoteDataFuji", "Short MakerNote");
00201 break;
00202 }
00203
00204 n->entries[tcount].tag = exif_get_short (buf + o, n->order);
00205 n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
00206 n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
00207 n->entries[tcount].order = n->order;
00208
00209 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataFuji",
00210 "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
00211 mnote_fuji_tag_get_name (n->entries[tcount].tag));
00212
00213
00214
00215
00216
00217 s = exif_format_get_size (n->entries[tcount].format) * n->entries[tcount].components;
00218 n->entries[tcount].size = s;
00219 if (s) {
00220 size_t dataofs = o + 8;
00221 if (s > 4)
00222
00223 dataofs = exif_get_long (buf + dataofs, n->order) + 6 + n->offset;
00224 if ((dataofs + s < dataofs) || (dataofs + s < s) ||
00225 (dataofs + s >= buf_size)) {
00226 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00227 "ExifMnoteDataFuji", "Tag data past end of "
00228 "buffer (%u >= %u)", dataofs + s, buf_size);
00229 continue;
00230 }
00231
00232 n->entries[tcount].data = exif_mem_alloc (en->mem, s);
00233 if (!n->entries[tcount].data) {
00234 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataFuji", s);
00235 continue;
00236 }
00237 memcpy (n->entries[tcount].data, buf + dataofs, s);
00238 }
00239
00240
00241 ++tcount;
00242 }
00243
00244 n->count = tcount;
00245 }
00246
00247 static unsigned int
00248 exif_mnote_data_fuji_count (ExifMnoteData *n)
00249 {
00250 return n ? ((ExifMnoteDataFuji *) n)->count : 0;
00251 }
00252
00253 static unsigned int
00254 exif_mnote_data_fuji_get_id (ExifMnoteData *d, unsigned int n)
00255 {
00256 ExifMnoteDataFuji *note = (ExifMnoteDataFuji *) d;
00257
00258 if (!note) return 0;
00259 if (note->count <= n) return 0;
00260 return note->entries[n].tag;
00261 }
00262
00263 static const char *
00264 exif_mnote_data_fuji_get_name (ExifMnoteData *d, unsigned int i)
00265 {
00266 ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
00267
00268 if (!n) return NULL;
00269 if (i >= n->count) return NULL;
00270 return mnote_fuji_tag_get_name (n->entries[i].tag);
00271 }
00272
00273 static const char *
00274 exif_mnote_data_fuji_get_title (ExifMnoteData *d, unsigned int i)
00275 {
00276 ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
00277
00278 if (!n) return NULL;
00279 if (i >= n->count) return NULL;
00280 return mnote_fuji_tag_get_title (n->entries[i].tag);
00281 }
00282
00283 static const char *
00284 exif_mnote_data_fuji_get_description (ExifMnoteData *d, unsigned int i)
00285 {
00286 ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
00287
00288 if (!n) return NULL;
00289 if (i >= n->count) return NULL;
00290 return mnote_fuji_tag_get_description (n->entries[i].tag);
00291 }
00292
00293 static void
00294 exif_mnote_data_fuji_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
00295 {
00296 ExifByteOrder o_orig;
00297 ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
00298 unsigned int i;
00299
00300 if (!n) return;
00301
00302 o_orig = n->order;
00303 n->order = o;
00304 for (i = 0; i < n->count; i++) {
00305 n->entries[i].order = o;
00306 exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
00307 n->entries[i].components, o_orig, o);
00308 }
00309 }
00310
00311 static void
00312 exif_mnote_data_fuji_set_offset (ExifMnoteData *n, unsigned int o)
00313 {
00314 if (n) ((ExifMnoteDataFuji *) n)->offset = o;
00315 }
00316
00317 int
00318 exif_mnote_data_fuji_identify (const ExifData *ed, const ExifEntry *e)
00319 {
00320 return ((e->size >= 12) && !memcmp (e->data, "FUJIFILM", 8));
00321 }
00322
00323 ExifMnoteData *
00324 exif_mnote_data_fuji_new (ExifMem *mem)
00325 {
00326 ExifMnoteData *d;
00327
00328 if (!mem) return NULL;
00329
00330 d = exif_mem_alloc (mem, sizeof (ExifMnoteDataFuji));
00331 if (!d) return NULL;
00332
00333 exif_mnote_data_construct (d, mem);
00334
00335
00336 d->methods.free = exif_mnote_data_fuji_free;
00337 d->methods.set_byte_order = exif_mnote_data_fuji_set_byte_order;
00338 d->methods.set_offset = exif_mnote_data_fuji_set_offset;
00339 d->methods.load = exif_mnote_data_fuji_load;
00340 d->methods.save = exif_mnote_data_fuji_save;
00341 d->methods.count = exif_mnote_data_fuji_count;
00342 d->methods.get_id = exif_mnote_data_fuji_get_id;
00343 d->methods.get_name = exif_mnote_data_fuji_get_name;
00344 d->methods.get_title = exif_mnote_data_fuji_get_title;
00345 d->methods.get_description = exif_mnote_data_fuji_get_description;
00346 d->methods.get_value = exif_mnote_data_fuji_get_value;
00347
00348 return d;
00349 }