/src/FreeImage/Source/Metadata/TagConversion.cpp
https://bitbucket.org/cabalistic/ogredeps/ · C++ · 1094 lines · 942 code · 99 blank · 53 comment · 81 complexity · ad5c0255e89dfcf60732bf9f6cab64a3 MD5 · raw file
- // ==========================================================
- // Tag to string conversion functions
- //
- // Design and implementation by
- // - Hervé Drolon <drolon@infonie.fr>
- //
- // This file is part of FreeImage 3
- //
- // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
- // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
- // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
- // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
- // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
- // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
- // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
- // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
- // THIS DISCLAIMER.
- //
- // Use at your own risk!
- // ==========================================================
- #ifdef _MSC_VER
- #pragma warning (disable : 4786) // identifier was truncated to 'number' characters
- #endif
- #include "FreeImage.h"
- #include "Utilities.h"
- #include "FreeImageTag.h"
- #include "FIRational.h"
- #define MAX_TEXT_EXTENT 512
- /**
- Convert a tag to a C string
- */
- static const char*
- ConvertAnyTag(FITAG *tag) {
- char format[MAX_TEXT_EXTENT];
- static std::string buffer;
- DWORD i;
- if(!tag)
- return NULL;
- buffer.erase();
-
- // convert the tag value to a string buffer
- FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag);
- DWORD tag_count = FreeImage_GetTagCount(tag);
- switch(tag_type) {
- case FIDT_BYTE: // N x 8-bit unsigned integer
- {
- BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag);
- sprintf(format, "%ld", (LONG) pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %ld", (LONG) pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_SHORT: // N x 16-bit unsigned integer
- {
- unsigned short *pvalue = (unsigned short *)FreeImage_GetTagValue(tag);
- sprintf(format, "%hu", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %hu", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_LONG: // N x 32-bit unsigned integer
- {
- DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag);
- sprintf(format, "%lu", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %lu", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_RATIONAL: // N x 64-bit unsigned fraction
- {
- DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
- sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]);
- buffer += format;
- }
- break;
- }
- case FIDT_SBYTE: // N x 8-bit signed integer
- {
- char *pvalue = (char*)FreeImage_GetTagValue(tag);
- sprintf(format, "%ld", (LONG) pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %ld", (LONG) pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_SSHORT: // N x 16-bit signed integer
- {
- short *pvalue = (short *)FreeImage_GetTagValue(tag);
- sprintf(format, "%hd", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %hd", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_SLONG: // N x 32-bit signed integer
- {
- LONG *pvalue = (LONG *)FreeImage_GetTagValue(tag);
- sprintf(format, "%ld", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %ld", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_SRATIONAL:// N x 64-bit signed fraction
- {
- LONG *pvalue = (LONG*)FreeImage_GetTagValue(tag);
- sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]);
- buffer += format;
- }
- break;
- }
- case FIDT_FLOAT: // N x 32-bit IEEE floating point
- {
- float *pvalue = (float *)FreeImage_GetTagValue(tag);
- sprintf(format, "%f", (double) pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, "%f", (double) pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_DOUBLE: // N x 64-bit IEEE floating point
- {
- double *pvalue = (double *)FreeImage_GetTagValue(tag);
- sprintf(format, "%f", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, "%f", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_IFD: // N x 32-bit unsigned integer (offset)
- {
- DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag);
- sprintf(format, "%X", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " %X", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_PALETTE: // N x 32-bit RGBQUAD
- {
- RGBQUAD *pvalue = (RGBQUAD *)FreeImage_GetTagValue(tag);
- sprintf(format, "(%d,%d,%d,%d)", pvalue[0].rgbRed, pvalue[0].rgbGreen, pvalue[0].rgbBlue, pvalue[0].rgbReserved);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, " (%d,%d,%d,%d)", pvalue[i].rgbRed, pvalue[i].rgbGreen, pvalue[i].rgbBlue, pvalue[i].rgbReserved);
- buffer += format;
- }
- break;
- }
-
- case FIDT_LONG8: // N x 64-bit unsigned integer
- {
- FIUINT64 *pvalue = (FIUINT64 *)FreeImage_GetTagValue(tag);
- sprintf(format, "%ld", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, "%ld", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_IFD8: // N x 64-bit unsigned integer (offset)
- {
- FIUINT64 *pvalue = (FIUINT64 *)FreeImage_GetTagValue(tag);
- sprintf(format, "%X", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, "%X", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_SLONG8: // N x 64-bit signed integer
- {
- FIINT64 *pvalue = (FIINT64 *)FreeImage_GetTagValue(tag);
- sprintf(format, "%ld", pvalue[0]);
- buffer += format;
- for(i = 1; i < tag_count; i++) {
- sprintf(format, "%ld", pvalue[i]);
- buffer += format;
- }
- break;
- }
- case FIDT_ASCII: // 8-bit bytes w/ last byte null
- case FIDT_UNDEFINED:// 8-bit untyped data
- default:
- {
- int max_size = MIN((int)FreeImage_GetTagLength(tag), (int)MAX_TEXT_EXTENT);
- if(max_size == MAX_TEXT_EXTENT)
- max_size--;
- memcpy(format, (char*)FreeImage_GetTagValue(tag), max_size);
- format[max_size] = '\0';
- buffer += format;
- break;
- }
- }
- return buffer.c_str();
- }
- /**
- Convert a Exif tag to a C string
- */
- static const char*
- ConvertExifTag(FITAG *tag) {
- char format[MAX_TEXT_EXTENT];
- static std::string buffer;
- if(!tag)
- return NULL;
- buffer.erase();
- // convert the tag value to a string buffer
- switch(FreeImage_GetTagID(tag)) {
- case TAG_ORIENTATION:
- {
- unsigned short orientation = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (orientation) {
- case 1:
- return "top, left side";
- case 2:
- return "top, right side";
- case 3:
- return "bottom, right side";
- case 4:
- return "bottom, left side";
- case 5:
- return "left side, top";
- case 6:
- return "right side, top";
- case 7:
- return "right side, bottom";
- case 8:
- return "left side, bottom";
- default:
- break;
- }
- }
- break;
- case TAG_REFERENCE_BLACK_WHITE:
- {
- DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
- if(FreeImage_GetTagLength(tag) == 48) {
- // reference black point value and reference white point value (ReferenceBlackWhite)
- int blackR = 0, whiteR = 0, blackG = 0, whiteG = 0, blackB = 0, whiteB = 0;
- if(pvalue[1])
- blackR = (int)(pvalue[0] / pvalue[1]);
- if(pvalue[3])
- whiteR = (int)(pvalue[2] / pvalue[3]);
- if(pvalue[5])
- blackG = (int)(pvalue[4] / pvalue[5]);
- if(pvalue[7])
- whiteG = (int)(pvalue[6] / pvalue[7]);
- if(pvalue[9])
- blackB = (int)(pvalue[8] / pvalue[9]);
- if(pvalue[11])
- whiteB = (int)(pvalue[10] / pvalue[11]);
- sprintf(format, "[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_COLOR_SPACE:
- {
- unsigned short colorSpace = *((unsigned short *)FreeImage_GetTagValue(tag));
- if (colorSpace == 1) {
- return "sRGB";
- } else if (colorSpace == 65535) {
- return "Undefined";
- } else {
- return "Unknown";
- }
- }
- break;
- case TAG_COMPONENTS_CONFIGURATION:
- {
- const char *componentStrings[7] = {"", "Y", "Cb", "Cr", "R", "G", "B"};
- BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag);
- for(DWORD i = 0; i < MIN((DWORD)4, FreeImage_GetTagCount(tag)); i++) {
- int j = pvalue[i];
- if(j > 0 && j < 7)
- buffer += componentStrings[j];
- }
- return buffer.c_str();
- }
- break;
- case TAG_COMPRESSED_BITS_PER_PIXEL:
- {
- FIRational r(tag);
- buffer = r.toString();
- if(buffer == "1")
- buffer += " bit/pixel";
- else
- buffer += " bits/pixel";
- return buffer.c_str();
- }
- break;
- case TAG_X_RESOLUTION:
- case TAG_Y_RESOLUTION:
- case TAG_FOCAL_PLANE_X_RES:
- case TAG_FOCAL_PLANE_Y_RES:
- case TAG_BRIGHTNESS_VALUE:
- case TAG_EXPOSURE_BIAS_VALUE:
- {
- FIRational r(tag);
- buffer = r.toString();
- return buffer.c_str();
- }
- break;
- case TAG_RESOLUTION_UNIT:
- case TAG_FOCAL_PLANE_UNIT:
- {
- unsigned short resolutionUnit = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (resolutionUnit) {
- case 1:
- return "(No unit)";
- case 2:
- return "inches";
- case 3:
- return "cm";
- default:
- break;
- }
- }
- break;
- case TAG_YCBCR_POSITIONING:
- {
- unsigned short yCbCrPosition = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (yCbCrPosition) {
- case 1:
- return "Center of pixel array";
- case 2:
- return "Datum point";
- default:
- break;
- }
- }
- break;
- case TAG_EXPOSURE_TIME:
- {
- FIRational r(tag);
- buffer = r.toString();
- buffer += " sec";
- return buffer.c_str();
- }
- break;
- case TAG_SHUTTER_SPEED_VALUE:
- {
- FIRational r(tag);
- LONG apexValue = r.longValue();
- LONG apexPower = 1 << apexValue;
- sprintf(format, "1/%d sec", (int)apexPower);
- buffer += format;
- return buffer.c_str();
- }
- break;
- case TAG_APERTURE_VALUE:
- case TAG_MAX_APERTURE_VALUE:
- {
- FIRational r(tag);
- double apertureApex = r.doubleValue();
- double rootTwo = sqrt((double)2);
- double fStop = pow(rootTwo, apertureApex);
- sprintf(format, "F%.1f", fStop);
- buffer += format;
- return buffer.c_str();
- }
- break;
- case TAG_FNUMBER:
- {
- FIRational r(tag);
- double fnumber = r.doubleValue();
- sprintf(format, "F%.1f", fnumber);
- buffer += format;
- return buffer.c_str();
- }
- break;
- case TAG_FOCAL_LENGTH:
- {
- FIRational r(tag);
- double focalLength = r.doubleValue();
- sprintf(format, "%.1f mm", focalLength);
- buffer += format;
- return buffer.c_str();
- }
- break;
- case TAG_FOCAL_LENGTH_IN_35MM_FILM:
- {
- unsigned short focalLength = *((unsigned short *)FreeImage_GetTagValue(tag));
- sprintf(format, "%hu mm", focalLength);
- buffer += format;
- return buffer.c_str();
- }
- break;
- case TAG_FLASH:
- {
- unsigned short flash = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch(flash) {
- case 0x0000:
- return "Flash did not fire";
- case 0x0001:
- return "Flash fired";
- case 0x0005:
- return "Strobe return light not detected";
- case 0x0007:
- return "Strobe return light detected";
- case 0x0009:
- return "Flash fired, compulsory flash mode";
- case 0x000D:
- return "Flash fired, compulsory flash mode, return light not detected";
- case 0x000F:
- return "Flash fired, compulsory flash mode, return light detected";
- case 0x0010:
- return "Flash did not fire, compulsory flash mode";
- case 0x0018:
- return "Flash did not fire, auto mode";
- case 0x0019:
- return "Flash fired, auto mode";
- case 0x001D:
- return "Flash fired, auto mode, return light not detected";
- case 0x001F:
- return "Flash fired, auto mode, return light detected";
- case 0x0020:
- return "No flash function";
- case 0x0041:
- return "Flash fired, red-eye reduction mode";
- case 0x0045:
- return "Flash fired, red-eye reduction mode, return light not detected";
- case 0x0047:
- return "Flash fired, red-eye reduction mode, return light detected";
- case 0x0049:
- return "Flash fired, compulsory flash mode, red-eye reduction mode";
- case 0x004D:
- return "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected";
- case 0x004F:
- return "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected";
- case 0x0059:
- return "Flash fired, auto mode, red-eye reduction mode";
- case 0x005D:
- return "Flash fired, auto mode, return light not detected, red-eye reduction mode";
- case 0x005F:
- return "Flash fired, auto mode, return light detected, red-eye reduction mode";
- default:
- sprintf(format, "Unknown (%d)", flash);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_SCENE_TYPE:
- {
- BYTE sceneType = *((BYTE*)FreeImage_GetTagValue(tag));
- if (sceneType == 1) {
- return "Directly photographed image";
- } else {
- sprintf(format, "Unknown (%d)", sceneType);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_SUBJECT_DISTANCE:
- {
- FIRational r(tag);
- if(r.getNumerator() == 0xFFFFFFFF) {
- return "Infinity";
- } else if(r.getNumerator() == 0) {
- return "Distance unknown";
- } else {
- double distance = r.doubleValue();
- sprintf(format, "%.3f meters", distance);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
-
- case TAG_METERING_MODE:
- {
- unsigned short meteringMode = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (meteringMode) {
- case 0:
- return "Unknown";
- case 1:
- return "Average";
- case 2:
- return "Center weighted average";
- case 3:
- return "Spot";
- case 4:
- return "Multi-spot";
- case 5:
- return "Multi-segment";
- case 6:
- return "Partial";
- case 255:
- return "(Other)";
- default:
- return "";
- }
- }
- break;
- case TAG_LIGHT_SOURCE:
- {
- unsigned short lightSource = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (lightSource) {
- case 0:
- return "Unknown";
- case 1:
- return "Daylight";
- case 2:
- return "Fluorescent";
- case 3:
- return "Tungsten (incandescent light)";
- case 4:
- return "Flash";
- case 9:
- return "Fine weather";
- case 10:
- return "Cloudy weather";
- case 11:
- return "Shade";
- case 12:
- return "Daylight fluorescent (D 5700 - 7100K)";
- case 13:
- return "Day white fluorescent (N 4600 - 5400K)";
- case 14:
- return "Cool white fluorescent (W 3900 - 4500K)";
- case 15:
- return "White fluorescent (WW 3200 - 3700K)";
- case 17:
- return "Standard light A";
- case 18:
- return "Standard light B";
- case 19:
- return "Standard light C";
- case 20:
- return "D55";
- case 21:
- return "D65";
- case 22:
- return "D75";
- case 23:
- return "D50";
- case 24:
- return "ISO studio tungsten";
- case 255:
- return "(Other)";
- default:
- return "";
- }
- }
- break;
- case TAG_SENSING_METHOD:
- {
- unsigned short sensingMethod = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (sensingMethod) {
- case 1:
- return "(Not defined)";
- case 2:
- return "One-chip color area sensor";
- case 3:
- return "Two-chip color area sensor";
- case 4:
- return "Three-chip color area sensor";
- case 5:
- return "Color sequential area sensor";
- case 7:
- return "Trilinear sensor";
- case 8:
- return "Color sequential linear sensor";
- default:
- return "";
- }
- }
- break;
- case TAG_FILE_SOURCE:
- {
- BYTE fileSource = *((BYTE*)FreeImage_GetTagValue(tag));
- if (fileSource == 3) {
- return "Digital Still Camera (DSC)";
- } else {
- sprintf(format, "Unknown (%d)", fileSource);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_EXPOSURE_PROGRAM:
- {
- unsigned short exposureProgram = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (exposureProgram) {
- case 1:
- return "Manual control";
- case 2:
- return "Program normal";
- case 3:
- return "Aperture priority";
- case 4:
- return "Shutter priority";
- case 5:
- return "Program creative (slow program)";
- case 6:
- return "Program action (high-speed program)";
- case 7:
- return "Portrait mode";
- case 8:
- return "Landscape mode";
- default:
- sprintf(format, "Unknown program (%d)", exposureProgram);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_CUSTOM_RENDERED:
- {
- unsigned short customRendered = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (customRendered) {
- case 0:
- return "Normal process";
- case 1:
- return "Custom process";
- default:
- sprintf(format, "Unknown rendering (%d)", customRendered);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_EXPOSURE_MODE:
- {
- unsigned short exposureMode = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (exposureMode) {
- case 0:
- return "Auto exposure";
- case 1:
- return "Manual exposure";
- case 2:
- return "Auto bracket";
- default:
- sprintf(format, "Unknown mode (%d)", exposureMode);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_WHITE_BALANCE:
- {
- unsigned short whiteBalance = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (whiteBalance) {
- case 0:
- return "Auto white balance";
- case 1:
- return "Manual white balance";
- default:
- sprintf(format, "Unknown (%d)", whiteBalance);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_SCENE_CAPTURE_TYPE:
- {
- unsigned short sceneType = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (sceneType) {
- case 0:
- return "Standard";
- case 1:
- return "Landscape";
- case 2:
- return "Portrait";
- case 3:
- return "Night scene";
- default:
- sprintf(format, "Unknown (%d)", sceneType);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_GAIN_CONTROL:
- {
- unsigned short gainControl = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (gainControl) {
- case 0:
- return "None";
- case 1:
- return "Low gain up";
- case 2:
- return "High gain up";
- case 3:
- return "Low gain down";
- case 4:
- return "High gain down";
- default:
- sprintf(format, "Unknown (%d)", gainControl);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_CONTRAST:
- {
- unsigned short contrast = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (contrast) {
- case 0:
- return "Normal";
- case 1:
- return "Soft";
- case 2:
- return "Hard";
- default:
- sprintf(format, "Unknown (%d)", contrast);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_SATURATION:
- {
- unsigned short saturation = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (saturation) {
- case 0:
- return "Normal";
- case 1:
- return "Low saturation";
- case 2:
- return "High saturation";
- default:
- sprintf(format, "Unknown (%d)", saturation);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_SHARPNESS:
- {
- unsigned short sharpness = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (sharpness) {
- case 0:
- return "Normal";
- case 1:
- return "Soft";
- case 2:
- return "Hard";
- default:
- sprintf(format, "Unknown (%d)", sharpness);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_SUBJECT_DISTANCE_RANGE:
- {
- unsigned short distanceRange = *((unsigned short *)FreeImage_GetTagValue(tag));
- switch (distanceRange) {
- case 0:
- return "unknown";
- case 1:
- return "Macro";
- case 2:
- return "Close view";
- case 3:
- return "Distant view";
- default:
- sprintf(format, "Unknown (%d)", distanceRange);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_ISO_SPEED_RATINGS:
- {
- unsigned short isoEquiv = *((unsigned short *)FreeImage_GetTagValue(tag));
- if (isoEquiv < 50) {
- isoEquiv *= 200;
- }
- sprintf(format, "%d", isoEquiv);
- buffer += format;
- return buffer.c_str();
- }
- break;
- case TAG_USER_COMMENT:
- {
- // first 8 bytes are used to define an ID code
- // we assume this is an ASCII string
- const BYTE *userComment = (BYTE*)FreeImage_GetTagValue(tag);
- for(DWORD i = 8; i < FreeImage_GetTagLength(tag); i++) {
- buffer += userComment[i];
- }
- buffer += '\0';
- return buffer.c_str();
- }
- break;
- case TAG_COMPRESSION:
- {
- WORD compression = *((WORD*)FreeImage_GetTagValue(tag));
- switch(compression) {
- case TAG_COMPRESSION_NONE:
- sprintf(format, "dump mode (%d)", compression);
- break;
- case TAG_COMPRESSION_CCITTRLE:
- sprintf(format, "CCITT modified Huffman RLE (%d)", compression);
- break;
- case TAG_COMPRESSION_CCITTFAX3:
- sprintf(format, "CCITT Group 3 fax encoding (%d)", compression);
- break;
- /*
- case TAG_COMPRESSION_CCITT_T4:
- sprintf(format, "CCITT T.4 (TIFF 6 name) (%d)", compression);
- break;
- */
- case TAG_COMPRESSION_CCITTFAX4:
- sprintf(format, "CCITT Group 4 fax encoding (%d)", compression);
- break;
- /*
- case TAG_COMPRESSION_CCITT_T6:
- sprintf(format, "CCITT T.6 (TIFF 6 name) (%d)", compression);
- break;
- */
- case TAG_COMPRESSION_LZW:
- sprintf(format, "LZW (%d)", compression);
- break;
- case TAG_COMPRESSION_OJPEG:
- sprintf(format, "!6.0 JPEG (%d)", compression);
- break;
- case TAG_COMPRESSION_JPEG:
- sprintf(format, "JPEG (%d)", compression);
- break;
- case TAG_COMPRESSION_NEXT:
- sprintf(format, "NeXT 2-bit RLE (%d)", compression);
- break;
- case TAG_COMPRESSION_CCITTRLEW:
- sprintf(format, "CCITTRLEW (%d)", compression);
- break;
- case TAG_COMPRESSION_PACKBITS:
- sprintf(format, "PackBits Macintosh RLE (%d)", compression);
- break;
- case TAG_COMPRESSION_THUNDERSCAN:
- sprintf(format, "ThunderScan RLE (%d)", compression);
- break;
- case TAG_COMPRESSION_PIXARFILM:
- sprintf(format, "Pixar companded 10bit LZW (%d)", compression);
- break;
- case TAG_COMPRESSION_PIXARLOG:
- sprintf(format, "Pixar companded 11bit ZIP (%d)", compression);
- break;
- case TAG_COMPRESSION_DEFLATE:
- sprintf(format, "Deflate compression (%d)", compression);
- break;
- case TAG_COMPRESSION_ADOBE_DEFLATE:
- sprintf(format, "Adobe Deflate compression (%d)", compression);
- break;
- case TAG_COMPRESSION_DCS:
- sprintf(format, "Kodak DCS encoding (%d)", compression);
- break;
- case TAG_COMPRESSION_JBIG:
- sprintf(format, "ISO JBIG (%d)", compression);
- break;
- case TAG_COMPRESSION_SGILOG:
- sprintf(format, "SGI Log Luminance RLE (%d)", compression);
- break;
- case TAG_COMPRESSION_SGILOG24:
- sprintf(format, "SGI Log 24-bit packed (%d)", compression);
- break;
- case TAG_COMPRESSION_JP2000:
- sprintf(format, "Leadtools JPEG2000 (%d)", compression);
- break;
- case TAG_COMPRESSION_LZMA:
- sprintf(format, "LZMA2 (%d)", compression);
- break;
- default:
- sprintf(format, "Unknown type (%d)", compression);
- break;
- }
- buffer += format;
- return buffer.c_str();
- }
- break;
- }
- return ConvertAnyTag(tag);
- }
- /**
- Convert a Exif GPS tag to a C string
- */
- static const char*
- ConvertExifGPSTag(FITAG *tag) {
- char format[MAX_TEXT_EXTENT];
- static std::string buffer;
- if(!tag)
- return NULL;
- buffer.erase();
- // convert the tag value to a string buffer
- switch(FreeImage_GetTagID(tag)) {
- case TAG_GPS_LATITUDE:
- case TAG_GPS_LONGITUDE:
- case TAG_GPS_TIME_STAMP:
- {
- DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag);
- if(FreeImage_GetTagLength(tag) == 24) {
- // dd:mm:ss or hh:mm:ss
- int dd = 0, mm = 0;
- double ss = 0;
- // convert to seconds
- if(pvalue[1])
- ss += ((double)pvalue[0] / (double)pvalue[1]) * 3600;
- if(pvalue[3])
- ss += ((double)pvalue[2] / (double)pvalue[3]) * 60;
- if(pvalue[5])
- ss += ((double)pvalue[4] / (double)pvalue[5]);
-
- // convert to dd:mm:ss.ss
- dd = (int)(ss / 3600);
- mm = (int)(ss / 60) - dd * 60;
- ss = ss - dd * 3600 - mm * 60;
- sprintf(format, "%d:%d:%.2f", dd, mm, ss);
- buffer += format;
- return buffer.c_str();
- }
- }
- break;
- case TAG_GPS_VERSION_ID:
- case TAG_GPS_LATITUDE_REF:
- case TAG_GPS_LONGITUDE_REF:
- case TAG_GPS_ALTITUDE_REF:
- case TAG_GPS_ALTITUDE:
- case TAG_GPS_SATELLITES:
- case TAG_GPS_STATUS:
- case TAG_GPS_MEASURE_MODE:
- case TAG_GPS_DOP:
- case TAG_GPS_SPEED_REF:
- case TAG_GPS_SPEED:
- case TAG_GPS_TRACK_REF:
- case TAG_GPS_TRACK:
- case TAG_GPS_IMG_DIRECTION_REF:
- case TAG_GPS_IMG_DIRECTION:
- case TAG_GPS_MAP_DATUM:
- case TAG_GPS_DEST_LATITUDE_REF:
- case TAG_GPS_DEST_LATITUDE:
- case TAG_GPS_DEST_LONGITUDE_REF:
- case TAG_GPS_DEST_LONGITUDE:
- case TAG_GPS_DEST_BEARING_REF:
- case TAG_GPS_DEST_BEARING:
- case TAG_GPS_DEST_DISTANCE_REF:
- case TAG_GPS_DEST_DISTANCE:
- case TAG_GPS_PROCESSING_METHOD:
- case TAG_GPS_AREA_INFORMATION:
- case TAG_GPS_DATE_STAMP:
- case TAG_GPS_DIFFERENTIAL:
- break;
- }
- return ConvertAnyTag(tag);
- }
- // ==========================================================
- // Tag to string conversion function
- //
- const char* DLL_CALLCONV
- FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make) {
- switch(model) {
- case FIMD_EXIF_MAIN:
- case FIMD_EXIF_EXIF:
- return ConvertExifTag(tag);
- case FIMD_EXIF_GPS:
- return ConvertExifGPSTag(tag);
- case FIMD_EXIF_MAKERNOTE:
- // We should use the Make string to select an appropriate conversion function
- // TO DO ...
- break;
- case FIMD_EXIF_INTEROP:
- default:
- break;
- }
- return ConvertAnyTag(tag);
- }