1548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* exif-mnote-data-olympus.c 2548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 3548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net> 4548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 5548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is free software; you can redistribute it and/or 6548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * modify it under the terms of the GNU Lesser General Public 7548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License as published by the Free Software Foundation; either 8548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * version 2 of the License, or (at your option) any later version. 9548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 10548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is distributed in the hope that it will be useful, 11548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * but WITHOUT ANY WARRANTY; without even the implied warranty of 12548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Lesser General Public License for more details. 14548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 15548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * You should have received a copy of the GNU Lesser General Public 16548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License along with this library; if not, write to the 17548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Boston, MA 02110-1301 USA. 19548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 20548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 21548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <config.h> 22548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include "exif-mnote-data-olympus.h" 23548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 24548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdlib.h> 25548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <string.h> 26548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdio.h> 27548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 28548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-utils.h> 29548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-data.h> 30548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 31548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define DEBUG 32548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 33548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best 34548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * not to in most cases because it seems to only affect the thumbnail tag 35548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * which is duplicated in IFD 1, and fixing the offset could actually cause 36548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * problems with other software that expects the broken form. 37548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 38548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */ 39548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 40548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic enum OlympusVersion 41548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_identify_variant (const unsigned char *buf, 42548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int buf_size); 43548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 44548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 45548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void 46548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n) 47548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 48548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteData *d = (ExifMnoteData *) n; 49548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int i; 50548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 51548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n) return; 52548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 53548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (n->entries) { 54548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen for (i = 0; i < n->count; i++) 55548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (n->entries[i].data) { 56548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mem_free (d->mem, n->entries[i].data); 57548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[i].data = NULL; 58548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 59548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mem_free (d->mem, n->entries); 60548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries = NULL; 61548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->count = 0; 62548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 63548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 64548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 65548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void 66548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_free (ExifMnoteData *n) 67548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 68548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n) return; 69548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 70548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n); 71548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 72548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 73548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic char * 74548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen) 75548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 76548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; 77548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 78548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!d || !val) return NULL; 79548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (i > n->count -1) return NULL; 80548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* 81548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 82548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Querying value for tag '%s'...", 83548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen mnote_olympus_tag_get_name (n->entries[i].tag)); 84548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen*/ 85548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen); 86548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 87548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 88548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 89548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 90548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 91548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/** 92548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @brief save the MnoteData from ne to buf 93548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 94548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @param ne extract the data from this structure 95548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @param *buf write the mnoteData to this buffer (buffer will be allocated) 96548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @param buf_size the size of the buffer 97548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 98548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void 99548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_save (ExifMnoteData *ne, 100548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned char **buf, unsigned int *buf_size) 101548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 102548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne; 103548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen size_t i, o, s, doff, base = 0, o2 = 6 + 2; 104548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen size_t datao = 0; 105548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned char *t; 106548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen size_t ts; 107548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 108548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n || !buf || !buf_size) return; 109548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 110548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* 111548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Allocate enough memory for all entries and the number of entries. 112548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 113548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf_size = 6 + 2 + 2 + n->count * 12; 114548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (n->version) { 115548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case olympusV1: 116548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case sanyoV1: 117548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case epsonV1: 118548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf = exif_mem_alloc (ne->mem, *buf_size); 119548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!*buf) { 120548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size); 121548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 122548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 123548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 124548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Write the header and the number of entries. */ 125548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen strcpy ((char *)*buf, n->version==sanyoV1?"SANYO": 126548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (n->version==epsonV1?"EPSON":"OLYMP")); 127548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + 6, n->order, (ExifShort) 1); 128548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen datao = n->offset; 129548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 130548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 131548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case olympusV2: 132548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf_size += 8-6 + 4; 133548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf = exif_mem_alloc (ne->mem, *buf_size); 134548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!*buf) { 135548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size); 136548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 137548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 138548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 139548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Write the header and the number of entries. */ 140548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen strcpy ((char *)*buf, "OLYMPUS"); 141548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + 8, n->order, (ExifShort) ( 142548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (n->order == EXIF_BYTE_ORDER_INTEL) ? 143548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ('I' << 8) | 'I' : 144548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ('M' << 8) | 'M')); 145548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + 10, n->order, (ExifShort) 3); 146548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 4; 147548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 148548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 149548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case nikonV1: 150548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen base = MNOTE_NIKON1_TAG_BASE; 151548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 152548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* v1 has offsets based to main IFD, not makernote IFD */ 153548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen datao += n->offset + 10; 154548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* subtract the size here, so the increment in the next case will not harm us */ 155548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf_size -= 8 + 2; 156548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Fall through to nikonV2 handler */ 157548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case nikonV2: 158548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Write out V0 files in V2 format */ 159548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case nikonV0: 160548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf_size += 8 + 2; 161548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf_size += 4; /* Next IFD pointer */ 162548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf = exif_mem_alloc (ne->mem, *buf_size); 163548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!*buf) { 164548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size); 165548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 166548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 167548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 168548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Write the header and the number of entries. */ 169548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen strcpy ((char *)*buf, "Nikon"); 170548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (*buf)[6] = n->version; 171548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 172548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (n->version != nikonV1) { 173548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + 10, n->order, (ExifShort) ( 174548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (n->order == EXIF_BYTE_ORDER_INTEL) ? 175548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ('I' << 8) | 'I' : 176548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ('M' << 8) | 'M')); 177548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A); 178548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_long (*buf + 14, n->order, (ExifShort) 8); 179548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 2 + 8; 180548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 181548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen datao -= 10; 182548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Reset next IFD pointer */ 183548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0); 184548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 185548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 186548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 187548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 188548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 189548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 190548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + o2, n->order, (ExifShort) n->count); 191548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 2; 192548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 193548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Save each entry */ 194548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen for (i = 0; i < n->count; i++) { 195548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o = o2 + i * 12; 196548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + o + 0, n->order, 197548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (ExifShort) (n->entries[i].tag - base)); 198548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_short (*buf + o + 2, n->order, 199548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (ExifShort) n->entries[i].format); 200548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_long (*buf + o + 4, n->order, 201548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[i].components); 202548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o += 8; 203548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen s = exif_format_get_size (n->entries[i].format) * 204548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[i].components; 205548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (s > 65536) { 206548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Corrupt data: EXIF data size is limited to the 207548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * maximum size of a JPEG segment (64 kb). 208548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 209548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen continue; 210548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 211548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (s > 4) { 212548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen doff = *buf_size; 213548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ts = *buf_size + s; 214548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen t = exif_mem_realloc (ne->mem, *buf, 215548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen sizeof (char) * ts); 216548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!t) { 217548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts); 218548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 219548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 220548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf = t; 221548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf_size = ts; 222548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_set_long (*buf + o, n->order, datao + doff); 223548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } else 224548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen doff = o; 225548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 226548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Write the data. */ 227548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (n->entries[i].data) { 228548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen memcpy (*buf + doff, n->entries[i].data, s); 229548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } else { 230548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Most certainly damaged input file */ 231548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen memset (*buf + doff, 0, s); 232548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 233548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 234548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 235548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 236548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void 237548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_load (ExifMnoteData *en, 238548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen const unsigned char *buf, unsigned int buf_size) 239548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 240548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en; 241548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifShort c; 242548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen size_t i, tcount, o, o2, datao = 6, base = 0; 243548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 244548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n || !buf || !buf_size) { 245548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 246548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifMnoteDataOlympus", "Short MakerNote"); 247548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 248548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 249548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 = 6 + n->offset; /* Start of interesting data */ 250548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((o2 + 10 < o2) || (o2 + 10 < 10) || (o2 + 10 > buf_size)) { 251548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 252548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifMnoteDataOlympus", "Short MakerNote"); 253548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 254548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 255548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 256548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* 257548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Olympus headers start with "OLYMP" and need to have at least 258548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the 259548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * number of entries, and 12 for one entry. 260548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 261548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Sanyo format is identical and uses identical tags except that 262548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * header starts with "SANYO". 263548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 264548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Epson format is identical and uses identical tags except that 265548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * header starts with "EPSON". 266548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 267548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Nikon headers start with "Nikon" (6 bytes including '\0'), 268548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * version number (1 or 2). 269548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 270548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Version 1 continues with 0, 1, 0, number_of_tags, 271548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * or just with number_of_tags (models D1H, D1X...). 272548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 273548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Version 2 continues with an unknown byte (0 or 10), 274548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * two unknown bytes (0), "MM" or "II", another byte 0 and 275548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * lastly 0x2A. 276548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 277548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2); 278548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (n->version) { 279548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case olympusV1: 280548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case sanyoV1: 281548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case epsonV1: 282548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 283548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Parsing Olympus/Sanyo/Epson maker note v1..."); 284548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 285548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* The number of entries is at position 8. */ 286548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (buf[o2 + 6] == 1) 287548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_INTEL; 288548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else if (buf[o2 + 6 + 1] == 1) 289548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_MOTOROLA; 290548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 8; 291548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (o2 + 2 > buf_size) return; 292548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen c = exif_get_short (buf + o2, n->order); 293548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((!(c & 0xFF)) && (c > 0x500)) { 294548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (n->order == EXIF_BYTE_ORDER_INTEL) { 295548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_MOTOROLA; 296548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } else { 297548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_INTEL; 298548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 299548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 300548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 301548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 302548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case olympusV2: 303548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Olympus S760, S770 */ 304548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen datao = o2; 305548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 8; 306548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 307548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...", 308548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]); 309548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 310548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I')) 311548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_INTEL; 312548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M')) 313548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_MOTOROLA; 314548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 315548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* The number of entries is at position 8+4. */ 316548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 4; 317548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 318548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 319548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case nikonV1: 320548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 6; 321548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (o2 >= buf_size) return; 322548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 323548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, " 324548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "%02x, %02x, %02x, %02x, %02x)...", 325548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], 326548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); 327548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 328548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Skip version number */ 329548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 1; 330548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 331548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Skip an unknown byte (00 or 0A). */ 332548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 1; 333548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 334548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen base = MNOTE_NIKON1_TAG_BASE; 335548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Fix endianness, if needed */ 336548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (o2 + 2 > buf_size) return; 337548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen c = exif_get_short (buf + o2, n->order); 338548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((!(c & 0xFF)) && (c > 0x500)) { 339548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (n->order == EXIF_BYTE_ORDER_INTEL) { 340548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_MOTOROLA; 341548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } else { 342548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_INTEL; 343548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 344548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 345548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 346548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 347548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case nikonV2: 348548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 6; 349548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (o2 >= buf_size) return; 350548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 351548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, " 352548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "%02x, %02x, %02x, %02x, %02x)...", 353548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], 354548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); 355548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 356548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Skip version number */ 357548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 1; 358548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 359548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Skip an unknown byte (00 or 0A). */ 360548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 1; 361548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 362548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Skip 2 unknown bytes (00 00). */ 363548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 2; 364548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 365548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* 366548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Byte order. From here the data offset 367548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * gets calculated. 368548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 369548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen datao = o2; 370548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (o2 >= buf_size) return; 371548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!strncmp ((char *)&buf[o2], "II", 2)) 372548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_INTEL; 373548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else if (!strncmp ((char *)&buf[o2], "MM", 2)) 374548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_MOTOROLA; 375548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else { 376548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, 377548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifMnoteDataOlympus", "Unknown " 378548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "byte order '%c%c'", buf[o2], 379548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2 + 1]); 380548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 381548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 382548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 2; 383548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 384548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Skip 2 unknown bytes (00 2A). */ 385548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 2; 386548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 387548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Go to where the number of entries is. */ 388548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (o2 + 4 > buf_size) return; 389548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 = datao + exif_get_long (buf + o2, n->order); 390548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 391548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 392548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case nikonV0: 393548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 394548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, " 395548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "%02x, %02x, %02x, %02x, %02x)...", 396548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], 397548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); 398548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* 00 1b is # of entries in Motorola order - the rest should also be in MM order */ 399548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = EXIF_BYTE_ORDER_MOTOROLA; 400548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 401548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 402548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 403548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 404548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Unknown Olympus variant %i.", n->version); 405548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 406548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 407548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 408548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Sanity check the offset */ 409548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((o2 + 2 < o2) || (o2 + 2 < 2) || (o2 + 2 > buf_size)) { 410548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 411548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifMnoteOlympus", "Short MakerNote"); 412548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 413548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 414548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 415548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Read the number of tags */ 416548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen c = exif_get_short (buf + o2, n->order); 417548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o2 += 2; 418548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 419548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Remove any old entries */ 420548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mnote_data_olympus_clear (n); 421548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 422548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Reserve enough space for all the possible MakerNote tags */ 423548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c); 424548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n->entries) { 425548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c); 426548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 427548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 428548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 429548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Parse all c entries, storing ones that are successfully parsed */ 430548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen tcount = 0; 431548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen for (i = c, o = o2; i; --i, o += 12) { 432548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen size_t s; 433548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) { 434548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 435548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifMnoteOlympus", "Short MakerNote"); 436548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 437548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 438548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 439548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base; 440548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].format = exif_get_short (buf + o + 2, n->order); 441548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].components = exif_get_long (buf + o + 4, n->order); 442548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].order = n->order; 443548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 444548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", 445548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Loading entry 0x%x ('%s')...", n->entries[tcount].tag, 446548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen mnote_olympus_tag_get_name (n->entries[tcount].tag)); 447548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", 448548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "0x%x %d %ld*(%d)", 449548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].tag, 450548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].format, 451548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].components, 452548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (int)exif_format_get_size(n->entries[tcount].format)); */ 453548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 454548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* 455548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Size? If bigger than 4 bytes, the actual data is not 456548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * in the entry but somewhere else (offset). 457548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 458548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen s = exif_format_get_size (n->entries[tcount].format) * 459548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].components; 460548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].size = s; 461548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (s) { 462548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen size_t dataofs = o + 8; 463548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (s > 4) { 464548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* The data in this case is merely a pointer */ 465548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen dataofs = exif_get_long (buf + dataofs, n->order) + datao; 466548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG 467548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when 468548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE 469548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * tag in its MakerNote. The offset is actually the absolute 470548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * position in the file instead of the position within the IFD. 471548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 472548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (dataofs + s > buf_size && n->version == sanyoV1) { 473548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* fix pointer */ 474548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen dataofs -= datao + 6; 475548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, 476548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifMnoteOlympus", 477548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Inconsistent thumbnail tag offset; attempting to recover"); 478548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 479548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#endif 480548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 481548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((dataofs + s < dataofs) || (dataofs + s < s) || 482548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen (dataofs + s > buf_size)) { 483548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (en->log, EXIF_LOG_CODE_DEBUG, 484548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifMnoteOlympus", 485548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Tag data past end of buffer (%u > %u)", 486548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen dataofs + s, buf_size); 487548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen continue; 488548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 489548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 490548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[tcount].data = exif_mem_alloc (en->mem, s); 491548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n->entries[tcount].data) { 492548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s); 493548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen continue; 494548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 495548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen memcpy (n->entries[tcount].data, buf + dataofs, s); 496548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 497548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 498548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Tag was successfully parsed */ 499548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ++tcount; 500548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 501548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Store the count of successfully parsed tags */ 502548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->count = tcount; 503548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 504548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 505548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic unsigned int 506548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_count (ExifMnoteData *n) 507548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 508548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return n ? ((ExifMnoteDataOlympus *) n)->count : 0; 509548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 510548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 511548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic unsigned int 512548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n) 513548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 514548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d; 515548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 516548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!note) return 0; 517548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (note->count <= n) return 0; 518548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return note->entries[n].tag; 519548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 520548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 521548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const char * 522548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i) 523548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 524548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; 525548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 526548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n) return NULL; 527548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (i >= n->count) return NULL; 528548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return mnote_olympus_tag_get_name (n->entries[i].tag); 529548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 530548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 531548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const char * 532548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i) 533548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 534548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; 535548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 536548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n) return NULL; 537548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (i >= n->count) return NULL; 538548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return mnote_olympus_tag_get_title (n->entries[i].tag); 539548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 540548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 541548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const char * 542548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i) 543548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 544548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; 545548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 546548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n) return NULL; 547548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (i >= n->count) return NULL; 548548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return mnote_olympus_tag_get_description (n->entries[i].tag); 549548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 550548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 551548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void 552548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o) 553548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 554548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifByteOrder o_orig; 555548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; 556548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int i; 557548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 558548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!n) return; 559548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 560548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen o_orig = n->order; 561548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->order = o; 562548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen for (i = 0; i < n->count; i++) { 563548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[i].order = o; 564548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_array_set_byte_order (n->entries[i].format, n->entries[i].data, 565548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen n->entries[i].components, o_orig, o); 566548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 567548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 568548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 569548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void 570548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o) 571548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 572548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (n) ((ExifMnoteDataOlympus *) n)->offset = o; 573548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 574548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 575548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic enum OlympusVersion 576548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_identify_variant (const unsigned char *buf, 577548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int buf_size) 578548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 579548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Olympus, Nikon, Sanyo, Epson */ 580548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (buf_size >= 8) { 581548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Match the terminating NUL character, too */ 582548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!memcmp (buf, "OLYMPUS", 8)) 583548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return olympusV2; 584548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else if (!memcmp (buf, "OLYMP", 6)) 585548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return olympusV1; 586548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else if (!memcmp (buf, "SANYO", 6)) 587548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return sanyoV1; 588548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else if (!memcmp (buf, "EPSON", 6)) 589548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return epsonV1; 590548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen else if (!memcmp (buf, "Nikon", 6)) { 591548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (buf[6]) { 592548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case 1: return nikonV1; 593548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case 2: return nikonV2; 594548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: return 0; /* Unrecognized Nikon variant */ 595548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 596548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 597548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 598548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 599548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Another variant of Nikon */ 600548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) { 601548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return nikonV0; 602548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 603548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 604548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return unrecognized; 605548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 606548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 607548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenint 608548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e) 609548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 610548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size); 611548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 612548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (variant == nikonV0) { 613548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* This variant needs some extra checking with the Make */ 614548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen char value[5]; 615548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE); 616548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen variant = unrecognized; 617548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 618548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (em) { 619548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen const char *v = exif_entry_get_value (em, value, sizeof(value)); 620548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (v && (!strncmp (v, "Nikon", sizeof(value)) || 621548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen !strncmp (v, "NIKON", sizeof(value)) )) 622548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* When saved, this variant will be written out like the 623548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * alternative nikonV2 form above instead 624548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 625548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen variant = nikonV0; 626548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 627548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 628548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 629548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return variant; 630548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 631548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 632548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 633548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifMnoteData * 634548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_new (ExifMem *mem) 635548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 636548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMnoteData *d; 637548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 638548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!mem) return NULL; 639548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 640548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus)); 641548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!d) return NULL; 642548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 643548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mnote_data_construct (d, mem); 644548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 645548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Set up function pointers */ 646548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.free = exif_mnote_data_olympus_free; 647548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order; 648548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.set_offset = exif_mnote_data_olympus_set_offset; 649548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.load = exif_mnote_data_olympus_load; 650548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.save = exif_mnote_data_olympus_save; 651548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.count = exif_mnote_data_olympus_count; 652548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.get_id = exif_mnote_data_olympus_get_id; 653548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.get_name = exif_mnote_data_olympus_get_name; 654548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.get_title = exif_mnote_data_olympus_get_title; 655548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.get_description = exif_mnote_data_olympus_get_description; 656548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d->methods.get_value = exif_mnote_data_olympus_get_value; 657548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 658548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return d; 659548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 660