00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "exif-mnote-data-pentax.h"
00023
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <stdio.h>
00027
00028 #include <libexif/exif-byte-order.h>
00029 #include <libexif/exif-utils.h>
00030
00031 static void
00032 exif_mnote_data_pentax_clear (ExifMnoteDataPentax *n)
00033 {
00034 ExifMnoteData *d = (ExifMnoteData *) n;
00035 unsigned int i;
00036
00037 if (!n) return;
00038
00039 if (n->entries) {
00040 for (i = 0; i < n->count; i++)
00041 if (n->entries[i].data) {
00042 exif_mem_free (d->mem, n->entries[i].data);
00043 n->entries[i].data = NULL;
00044 }
00045 exif_mem_free (d->mem, n->entries);
00046 n->entries = NULL;
00047 n->count = 0;
00048 }
00049 }
00050
00051 static void
00052 exif_mnote_data_pentax_free (ExifMnoteData *n)
00053 {
00054 if (!n) return;
00055
00056 exif_mnote_data_pentax_clear ((ExifMnoteDataPentax *) n);
00057 }
00058
00059 static char *
00060 exif_mnote_data_pentax_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
00061 {
00062 ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) d;
00063
00064 if (!n) return NULL;
00065 if (n->count <= i) return NULL;
00066 return mnote_pentax_entry_get_value (&n->entries[i], val, maxlen);
00067 }
00068
00076 static void
00077 exif_mnote_data_pentax_save (ExifMnoteData *ne,
00078 unsigned char **buf, unsigned int *buf_size)
00079 {
00080 ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) ne;
00081 size_t i,
00082 base = 0,
00083 o2 = 4 + 2;
00084 size_t datao = n->offset;
00085
00086
00087 if (!n || !buf || !buf_size) return;
00088
00089
00090
00091
00092
00093 *buf_size = o2 + 2 + n->count * 12 + 4;
00094 switch (n->version) {
00095 case casioV2:
00096 base = MNOTE_PENTAX2_TAG_BASE;
00097 *buf = exif_mem_alloc (ne->mem, *buf_size);
00098 if (!*buf) {
00099 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
00100 return;
00101 }
00102
00103 strcpy ((char *)*buf, "QVC");
00104 exif_set_short (*buf + 4, n->order, (ExifShort) 0);
00105
00106 break;
00107
00108 case pentaxV3:
00109 base = MNOTE_PENTAX2_TAG_BASE;
00110 *buf = exif_mem_alloc (ne->mem, *buf_size);
00111 if (!*buf) {
00112 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
00113 return;
00114 }
00115
00116
00117 strcpy ((char *)*buf, "AOC");
00118 exif_set_short (*buf + 4, n->order, (ExifShort) (
00119 (n->order == EXIF_BYTE_ORDER_INTEL) ?
00120 ('I' << 8) | 'I' :
00121 ('M' << 8) | 'M'));
00122 break;
00123
00124 case pentaxV2:
00125 base = MNOTE_PENTAX2_TAG_BASE;
00126 *buf = exif_mem_alloc (ne->mem, *buf_size);
00127 if (!*buf) {
00128 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
00129 return;
00130 }
00131
00132
00133 strcpy ((char *)*buf, "AOC");
00134 exif_set_short (*buf + 4, n->order, (ExifShort) 0);
00135 break;
00136
00137 case pentaxV1:
00138
00139
00140 *buf_size -= 6;
00141 o2 -= 6;
00142 *buf = exif_mem_alloc (ne->mem, *buf_size);
00143 if (!*buf) {
00144 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
00145 return;
00146 }
00147 break;
00148
00149 default:
00150
00151 return;
00152 }
00153
00154
00155 exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
00156 o2 += 2;
00157
00158
00159 for (i = 0; i < n->count; i++) {
00160 size_t doff;
00161 size_t s;
00162 unsigned char *t;
00163 size_t o = o2 + i * 12;
00164 exif_set_short (*buf + o + 0, n->order,
00165 (ExifShort) (n->entries[i].tag - base));
00166 exif_set_short (*buf + o + 2, n->order,
00167 (ExifShort) n->entries[i].format);
00168 exif_set_long (*buf + o + 4, n->order,
00169 n->entries[i].components);
00170 o += 8;
00171 s = exif_format_get_size (n->entries[i].format) *
00172 n->entries[i].components;
00173 if (s > 65536) {
00174
00175
00176
00177 continue;
00178 }
00179 if (s > 4) {
00180 size_t ts = *buf_size + s;
00181 doff = *buf_size;
00182 t = exif_mem_realloc (ne->mem, *buf,
00183 sizeof (char) * ts);
00184 if (!t) {
00185 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", ts);
00186 return;
00187 }
00188 *buf = t;
00189 *buf_size = ts;
00190 exif_set_long (*buf + o, n->order, datao + doff);
00191 } else
00192 doff = o;
00193
00194
00195 if (n->entries[i].data) {
00196 memcpy (*buf + doff, n->entries[i].data, s);
00197 } else {
00198
00199 memset (*buf + doff, 0, s);
00200 }
00201 }
00202
00203
00204 if (*buf_size < (o2 + n->count * 12 + 4)) {
00205 exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteDataPentax",
00206 "Buffer overflow");
00207 }
00208
00209
00210 exif_set_long (*buf + o2 + n->count * 12, n->order, 0);
00211 }
00212
00213 static void
00214 exif_mnote_data_pentax_load (ExifMnoteData *en,
00215 const unsigned char *buf, unsigned int buf_size)
00216 {
00217 ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) en;
00218 size_t i, tcount, o, datao, base = 0;
00219 ExifShort c;
00220
00221 if (!n || !buf || !buf_size) {
00222 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00223 "ExifMnoteDataPentax", "Short MakerNote");
00224 return;
00225 }
00226 datao = 6 + n->offset;
00227 if ((datao + 8 < datao) || (datao + 8 < 8) || (datao + 8 > buf_size)) {
00228 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00229 "ExifMnoteDataPentax", "Short MakerNote");
00230 return;
00231 }
00232
00233
00234 if (!memcmp(buf + datao, "AOC", 4)) {
00235 if ((buf[datao + 4] == 'I') && (buf[datao + 5] == 'I')) {
00236 n->version = pentaxV3;
00237 n->order = EXIF_BYTE_ORDER_INTEL;
00238 } else if ((buf[datao + 4] == 'M') && (buf[datao + 5] == 'M')) {
00239 n->version = pentaxV3;
00240 n->order = EXIF_BYTE_ORDER_MOTOROLA;
00241 } else {
00242
00243 n->version = pentaxV2;
00244 }
00245 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax",
00246 "Parsing Pentax maker note v%d...", (int)n->version);
00247 datao += 4 + 2;
00248 base = MNOTE_PENTAX2_TAG_BASE;
00249 } else if (!memcmp(buf + datao, "QVC", 4)) {
00250 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax",
00251 "Parsing Casio maker note v2...");
00252 n->version = casioV2;
00253 base = MNOTE_CASIO2_TAG_BASE;
00254 datao += 4 + 2;
00255 } else {
00256
00257 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax",
00258 "Parsing Pentax maker note v1...");
00259 n->version = pentaxV1;
00260 }
00261
00262
00263 c = exif_get_short (buf + datao, n->order);
00264 datao += 2;
00265
00266
00267 exif_mnote_data_pentax_clear (n);
00268
00269
00270 n->entries = exif_mem_alloc (en->mem, sizeof (MnotePentaxEntry) * c);
00271 if (!n->entries) {
00272 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataPentax", sizeof (MnotePentaxEntry) * c);
00273 return;
00274 }
00275
00276
00277 tcount = 0;
00278 for (i = c, o = datao; i; --i, o += 12) {
00279 size_t s;
00280 if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
00281 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
00282 "ExifMnoteDataPentax", "Short MakerNote");
00283 break;
00284 }
00285
00286 n->entries[tcount].tag = exif_get_short (buf + o + 0, n->order) + base;
00287 n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
00288 n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
00289 n->entries[tcount].order = n->order;
00290
00291 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnotePentax",
00292 "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
00293 mnote_pentax_tag_get_name (n->entries[tcount].tag));
00294
00295
00296
00297
00298
00299 s = exif_format_get_size (n->entries[tcount].format) *
00300 n->entries[tcount].components;
00301 n->entries[tcount].size = s;
00302 if (s) {
00303 size_t dataofs = o + 8;
00304 if (s > 4)
00305
00306 dataofs = exif_get_long (buf + dataofs, n->order) + 6;
00307 if ((dataofs + s < dataofs) || (dataofs + s < s) ||
00308 (dataofs + s > buf_size)) {
00309 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
00310 "ExifMnoteDataPentax", "Tag data past end "
00311 "of buffer (%u > %u)", dataofs + s, buf_size);
00312 continue;
00313 }
00314
00315 n->entries[tcount].data = exif_mem_alloc (en->mem, s);
00316 if (!n->entries[tcount].data) {
00317 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataPentax", s);
00318 continue;
00319 }
00320 memcpy (n->entries[tcount].data, buf + dataofs, s);
00321 }
00322
00323
00324 ++tcount;
00325 }
00326
00327 n->count = tcount;
00328 }
00329
00330 static unsigned int
00331 exif_mnote_data_pentax_count (ExifMnoteData *n)
00332 {
00333 return n ? ((ExifMnoteDataPentax *) n)->count : 0;
00334 }
00335
00336 static unsigned int
00337 exif_mnote_data_pentax_get_id (ExifMnoteData *d, unsigned int n)
00338 {
00339 ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
00340
00341 if (!note) return 0;
00342 if (note->count <= n) return 0;
00343 return note->entries[n].tag;
00344 }
00345
00346 static const char *
00347 exif_mnote_data_pentax_get_name (ExifMnoteData *d, unsigned int n)
00348 {
00349 ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
00350
00351 if (!note) return NULL;
00352 if (note->count <= n) return NULL;
00353 return mnote_pentax_tag_get_name (note->entries[n].tag);
00354 }
00355
00356 static const char *
00357 exif_mnote_data_pentax_get_title (ExifMnoteData *d, unsigned int n)
00358 {
00359 ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
00360
00361 if (!note) return NULL;
00362 if (note->count <= n) return NULL;
00363 return mnote_pentax_tag_get_title (note->entries[n].tag);
00364 }
00365
00366 static const char *
00367 exif_mnote_data_pentax_get_description (ExifMnoteData *d, unsigned int n)
00368 {
00369 ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
00370
00371 if (!note) return NULL;
00372 if (note->count <= n) return NULL;
00373 return mnote_pentax_tag_get_description (note->entries[n].tag);
00374 }
00375
00376 static void
00377 exif_mnote_data_pentax_set_offset (ExifMnoteData *d, unsigned int o)
00378 {
00379 if (d) ((ExifMnoteDataPentax *) d)->offset = o;
00380 }
00381
00382 static void
00383 exif_mnote_data_pentax_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
00384 {
00385 ExifByteOrder o_orig;
00386 ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) d;
00387 unsigned int i;
00388
00389 if (!n) return;
00390
00391 o_orig = n->order;
00392 n->order = o;
00393 for (i = 0; i < n->count; i++) {
00394 n->entries[i].order = o;
00395 exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
00396 n->entries[i].components, o_orig, o);
00397 }
00398 }
00399
00400 int
00401 exif_mnote_data_pentax_identify (const ExifData *ed, const ExifEntry *e)
00402 {
00403 if ((e->size >= 8) && !memcmp (e->data, "AOC", 4)) {
00404 if (((e->data[4] == 'I') && (e->data[5] == 'I')) ||
00405 ((e->data[4] == 'M') && (e->data[5] == 'M')))
00406 return pentaxV3;
00407 else
00408
00409 return pentaxV2;
00410 }
00411
00412 if ((e->size >= 8) && !memcmp (e->data, "QVC", 4))
00413 return casioV2;
00414
00415
00416
00417 if ((e->size >= 2) && (e->data[0] == 0x00) && (e->data[1] == 0x1b))
00418 return pentaxV1;
00419
00420 return 0;
00421 }
00422
00423 ExifMnoteData *
00424 exif_mnote_data_pentax_new (ExifMem *mem)
00425 {
00426 ExifMnoteData *d;
00427
00428 if (!mem) return NULL;
00429
00430 d = exif_mem_alloc (mem, sizeof (ExifMnoteDataPentax));
00431 if (!d) return NULL;
00432
00433 exif_mnote_data_construct (d, mem);
00434
00435
00436 d->methods.free = exif_mnote_data_pentax_free;
00437 d->methods.set_byte_order = exif_mnote_data_pentax_set_byte_order;
00438 d->methods.set_offset = exif_mnote_data_pentax_set_offset;
00439 d->methods.load = exif_mnote_data_pentax_load;
00440 d->methods.save = exif_mnote_data_pentax_save;
00441 d->methods.count = exif_mnote_data_pentax_count;
00442 d->methods.get_id = exif_mnote_data_pentax_get_id;
00443 d->methods.get_name = exif_mnote_data_pentax_get_name;
00444 d->methods.get_title = exif_mnote_data_pentax_get_title;
00445 d->methods.get_description = exif_mnote_data_pentax_get_description;
00446 d->methods.get_value = exif_mnote_data_pentax_get_value;
00447
00448 return d;
00449 }