Mercurial > geeqie.yaz
comparison src/exif.c @ 110:9fbf210edc6f
Tue Nov 14 15:36:14 2006 John Ellis <johne@verizon.net>
* exif.[ch]: Fix memory alignment issues, bug #1593252.
author | gqview |
---|---|
date | Tue, 14 Nov 2006 20:39:14 +0000 |
parents | a01d8c49ca2f |
children | 50fc73e08550 |
comparison
equal
deleted
inserted
replaced
109:1818abf306c1 | 110:9fbf210edc6f |
---|---|
582 *------------------------------------------------------------------- | 582 *------------------------------------------------------------------- |
583 * byte order utils | 583 * byte order utils |
584 *------------------------------------------------------------------- | 584 *------------------------------------------------------------------- |
585 */ | 585 */ |
586 | 586 |
587 /* note: the align_buf is used to avoid alignment issues (on sparc) */ | |
588 | |
587 guint16 exif_byte_get_int16(unsigned char *f, ExifByteOrder bo) | 589 guint16 exif_byte_get_int16(unsigned char *f, ExifByteOrder bo) |
588 { | 590 { |
591 guint16 align_buf; | |
592 | |
593 memcpy(&align_buf, f, sizeof(guint16)); | |
594 | |
589 if (bo == EXIF_BYTE_ORDER_INTEL) | 595 if (bo == EXIF_BYTE_ORDER_INTEL) |
590 return GUINT16_FROM_LE(*(guint16*)f); | 596 return GUINT16_FROM_LE(align_buf); |
591 else | 597 else |
592 return GUINT16_FROM_BE(*(guint16*)f); | 598 return GUINT16_FROM_BE(align_buf); |
593 } | 599 } |
594 | 600 |
595 guint32 exif_byte_get_int32(unsigned char *f, ExifByteOrder bo) | 601 guint32 exif_byte_get_int32(unsigned char *f, ExifByteOrder bo) |
596 { | 602 { |
603 guint32 align_buf; | |
604 | |
605 memcpy(&align_buf, f, sizeof(guint32)); | |
606 | |
597 if (bo == EXIF_BYTE_ORDER_INTEL) | 607 if (bo == EXIF_BYTE_ORDER_INTEL) |
598 return GUINT32_FROM_LE(*(guint32*)f); | 608 return GUINT32_FROM_LE(align_buf); |
599 else | 609 else |
600 return GUINT32_FROM_BE(*(guint32*)f); | 610 return GUINT32_FROM_BE(align_buf); |
601 } | 611 } |
602 | 612 |
603 guint16 exif_byte_put_int16(guint16 n, ExifByteOrder bo) | 613 void exif_byte_put_int16(unsigned char *f, guint16 n, ExifByteOrder bo) |
604 { | 614 { |
605 #if G_BYTE_ORDER == G_LITTLE_ENDIAN | 615 guint16 align_buf; |
606 if (bo == EXIF_BYTE_ORDER_MOTOROLA) | 616 |
607 #else | |
608 if (bo == EXIF_BYTE_ORDER_INTEL) | 617 if (bo == EXIF_BYTE_ORDER_INTEL) |
609 #endif | 618 { |
610 return GUINT16_SWAP_LE_BE(n); | 619 align_buf = GUINT16_TO_LE(n); |
620 } | |
611 else | 621 else |
612 return n; | 622 { |
613 } | 623 align_buf = GUINT16_TO_BE(n); |
614 | 624 } |
615 guint32 exif_byte_put_int32(guint32 n, ExifByteOrder bo) | 625 |
616 { | 626 memcpy(f, &align_buf, sizeof(guint16)); |
617 #if G_BYTE_ORDER == G_LITTLE_ENDIAN | 627 } |
618 if (bo == EXIF_BYTE_ORDER_MOTOROLA) | 628 |
619 #else | 629 void exif_byte_put_int32(unsigned char *f, guint32 n, ExifByteOrder bo) |
630 { | |
631 guint32 align_buf; | |
632 | |
620 if (bo == EXIF_BYTE_ORDER_INTEL) | 633 if (bo == EXIF_BYTE_ORDER_INTEL) |
621 #endif | 634 { |
622 return GUINT32_SWAP_LE_BE(n); | 635 align_buf = GUINT32_TO_LE(n); |
636 } | |
623 else | 637 else |
624 return n; | 638 { |
625 } | 639 align_buf = GUINT32_TO_BE(n); |
640 } | |
641 | |
642 memcpy(f, &align_buf, sizeof(guint32)); | |
643 } | |
644 | |
626 | 645 |
627 /* | 646 /* |
628 *------------------------------------------------------------------- | 647 *------------------------------------------------------------------- |
629 * IFD utils | 648 * IFD utils |
630 *------------------------------------------------------------------- | 649 *------------------------------------------------------------------- |
1222 case EXIF_FORMAT_SHORT_UNSIGNED: | 1241 case EXIF_FORMAT_SHORT_UNSIGNED: |
1223 if (ne == 1 && marker->list) | 1242 if (ne == 1 && marker->list) |
1224 { | 1243 { |
1225 gchar *result; | 1244 gchar *result; |
1226 | 1245 |
1227 result = exif_text_list_find_value(marker->list, ((unsigned short *)data)[0]); | 1246 result = exif_text_list_find_value(marker->list, ((guint16 *)data)[0]); |
1228 string = g_string_append(string, result); | 1247 string = g_string_append(string, result); |
1229 g_free(result); | 1248 g_free(result); |
1230 } | 1249 } |
1231 else for (i = 0; i < ne; i++) | 1250 else for (i = 0; i < ne; i++) |
1232 { | 1251 { |
1233 g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", | 1252 g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", |
1234 ((unsigned short *)data)[i]); | 1253 ((guint16 *)data)[i]); |
1235 } | 1254 } |
1236 break; | 1255 break; |
1237 case EXIF_FORMAT_LONG_UNSIGNED: | 1256 case EXIF_FORMAT_LONG_UNSIGNED: |
1238 for (i = 0; i < ne; i++) | 1257 for (i = 0; i < ne; i++) |
1239 { | 1258 { |
1240 g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", | 1259 g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", |
1241 ((unsigned long *)data)[i]); | 1260 (unsigned long int)((guint32 *)data)[i]); |
1242 } | 1261 } |
1243 break; | 1262 break; |
1244 case EXIF_FORMAT_RATIONAL_UNSIGNED: | 1263 case EXIF_FORMAT_RATIONAL_UNSIGNED: |
1245 for (i = 0; i < ne; i++) | 1264 for (i = 0; i < ne; i++) |
1246 { | 1265 { |
1253 break; | 1272 break; |
1254 case EXIF_FORMAT_SHORT: | 1273 case EXIF_FORMAT_SHORT: |
1255 for (i = 0; i < ne; i++) | 1274 for (i = 0; i < ne; i++) |
1256 { | 1275 { |
1257 g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", | 1276 g_string_append_printf(string, "%s%hd", (i > 0) ? ", " : "", |
1258 ((short *)data)[i]); | 1277 ((gint16 *)data)[i]); |
1259 } | 1278 } |
1260 break; | 1279 break; |
1261 case EXIF_FORMAT_LONG: | 1280 case EXIF_FORMAT_LONG: |
1262 for (i = 0; i < ne; i++) | 1281 for (i = 0; i < ne; i++) |
1263 { | 1282 { |
1264 g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", | 1283 g_string_append_printf(string, "%s%ld", (i > 0) ? ", " : "", |
1265 ((long *)data)[i]); | 1284 (long int)((gint32 *)data)[i]); |
1266 } | 1285 } |
1267 break; | 1286 break; |
1268 case EXIF_FORMAT_RATIONAL: | 1287 case EXIF_FORMAT_RATIONAL: |
1269 for (i = 0; i < ne; i++) | 1288 for (i = 0; i < ne; i++) |
1270 { | 1289 { |
1302 if (!item) return FALSE; | 1321 if (!item) return FALSE; |
1303 | 1322 |
1304 switch (item->format) | 1323 switch (item->format) |
1305 { | 1324 { |
1306 case EXIF_FORMAT_SHORT: | 1325 case EXIF_FORMAT_SHORT: |
1307 *value = (gint)(((short *)(item->data))[0]); | 1326 *value = (gint)(((gint16 *)(item->data))[0]); |
1308 return TRUE; | 1327 return TRUE; |
1309 break; | 1328 break; |
1310 case EXIF_FORMAT_SHORT_UNSIGNED: | 1329 case EXIF_FORMAT_SHORT_UNSIGNED: |
1311 *value = (gint)(((unsigned short *)(item->data))[0]); | 1330 *value = (gint)(((guint16 *)(item->data))[0]); |
1312 return TRUE; | 1331 return TRUE; |
1313 break; | 1332 break; |
1314 case EXIF_FORMAT_LONG: | 1333 case EXIF_FORMAT_LONG: |
1315 *value = (gint)(((long *)(item->data))[0]); | 1334 *value = (gint)(((gint32 *)(item->data))[0]); |
1316 return TRUE; | 1335 return TRUE; |
1317 break; | 1336 break; |
1318 case EXIF_FORMAT_LONG_UNSIGNED: | 1337 case EXIF_FORMAT_LONG_UNSIGNED: |
1319 /* FIXME: overflow possible */ | 1338 /* FIXME: overflow possible */ |
1320 *value = (gint)(((unsigned long *)(item->data))[0]); | 1339 *value = (gint)(((guint32 *)(item->data))[0]); |
1321 return TRUE; | 1340 return TRUE; |
1322 default: | 1341 default: |
1323 /* all other type return FALSE */ | 1342 /* all other type return FALSE */ |
1324 break; | 1343 break; |
1325 } | 1344 } |