1
// ==========================================================
2
// Tag manipulation functions
4
// Design and implementation by
5
// - Herv� Drolon <drolon@infonie.fr>
7
// This file is part of FreeImage 3
9
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
10
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
11
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
12
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
13
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
14
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
15
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
16
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
19
// Use at your own risk!
20
// ==========================================================
23
#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
26
#include "FreeImage.h"
27
#include "Utilities.h"
28
#include "FreeImageTag.h"
30
// --------------------------------------------------------------------------
31
// FITAG header definition
32
// --------------------------------------------------------------------------
34
FI_STRUCT (FITAGHEADER) {
35
char *key; // tag field name
36
char *description; // tag description
38
WORD type; // tag data type (see FREE_IMAGE_MDTYPE)
39
DWORD count; // number of components (in 'tag data types' units)
40
DWORD length; // value length in bytes
41
void *value; // tag value
44
// --------------------------------------------------------------------------
45
// FITAG creation / destruction
46
// --------------------------------------------------------------------------
49
FreeImage_CreateTag() {
50
FITAG *tag = (FITAG *)malloc(sizeof(FITAG));
53
unsigned tag_size = sizeof(FITAGHEADER);
54
tag->data = (BYTE *)malloc(tag_size * sizeof(BYTE));
55
if (tag->data != NULL) {
56
memset(tag->data, 0, tag_size);
66
FreeImage_DeleteTag(FITAG *tag) {
68
if (NULL != tag->data) {
69
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
71
free(tag_header->key);
72
free(tag_header->description);
73
free(tag_header->value);
83
FreeImage_CloneTag(FITAG *tag) {
87
FITAG *clone = FreeImage_CreateTag();
88
if(!clone) return NULL;
91
FITAGHEADER *src_tag = (FITAGHEADER *)tag->data;
92
FITAGHEADER *dst_tag = (FITAGHEADER *)clone->data;
95
dst_tag->id = src_tag->id;
98
dst_tag->key = (char*)malloc((strlen(src_tag->key) + 1) * sizeof(char));
99
strcpy(dst_tag->key, src_tag->key);
102
if(src_tag->description) {
103
dst_tag->description = (char*)malloc((strlen(src_tag->description) + 1) * sizeof(char));
104
strcpy(dst_tag->description, src_tag->description);
107
dst_tag->type = src_tag->type;
109
dst_tag->count = src_tag->count;
111
dst_tag->length = src_tag->length;
113
switch(dst_tag->type) {
115
dst_tag->value = (char*)malloc((strlen((char*)src_tag->value) + 1) * sizeof(char));
116
strcpy((char*)dst_tag->value, (char*)src_tag->value);
119
dst_tag->value = (BYTE*)malloc(src_tag->length * sizeof(BYTE));
120
memcpy(dst_tag->value, src_tag->value, src_tag->length);
127
// --------------------------------------------------------------------------
128
// FITAG getters / setters
129
// --------------------------------------------------------------------------
131
const char * DLL_CALLCONV
132
FreeImage_GetTagKey(FITAG *tag) {
133
return tag ? ((FITAGHEADER *)tag->data)->key : 0;
136
const char * DLL_CALLCONV
137
FreeImage_GetTagDescription(FITAG *tag) {
138
return tag ? ((FITAGHEADER *)tag->data)->description : 0;
142
FreeImage_GetTagID(FITAG *tag) {
143
return tag ? ((FITAGHEADER *)tag->data)->id : 0;
146
FREE_IMAGE_MDTYPE DLL_CALLCONV
147
FreeImage_GetTagType(FITAG *tag) {
148
return tag ? (FREE_IMAGE_MDTYPE)(((FITAGHEADER *)tag->data)->type) : FIDT_NOTYPE;
152
FreeImage_GetTagCount(FITAG *tag) {
153
return tag ? ((FITAGHEADER *)tag->data)->count : 0;
157
FreeImage_GetTagLength(FITAG *tag) {
158
return tag ? ((FITAGHEADER *)tag->data)->length : 0;
161
const void *DLL_CALLCONV
162
FreeImage_GetTagValue(FITAG *tag) {
163
return tag ? ((FITAGHEADER *)tag->data)->value : 0;
167
FreeImage_SetTagKey(FITAG *tag, const char *key) {
169
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
170
if(tag_header->key) free(tag_header->key);
171
tag_header->key = (char*)malloc(strlen(key) + 1);
172
strcpy(tag_header->key, key);
179
FreeImage_SetTagDescription(FITAG *tag, const char *description) {
180
if(tag && description) {
181
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
182
if(tag_header->description) free(tag_header->description);
183
tag_header->description = (char*)malloc(strlen(description) + 1);
184
strcpy(tag_header->description, description);
191
FreeImage_SetTagID(FITAG *tag, WORD id) {
193
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
201
FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type) {
203
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
204
tag_header->type = (WORD)type;
211
FreeImage_SetTagCount(FITAG *tag, DWORD count) {
213
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
214
tag_header->count = count;
221
FreeImage_SetTagLength(FITAG *tag, DWORD length) {
223
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
224
tag_header->length = length;
231
FreeImage_SetTagValue(FITAG *tag, const void *value) {
233
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
234
// first, check the tag
235
if(tag_header->count * FreeImage_TagDataWidth((FREE_IMAGE_MDTYPE)tag_header->type) != tag_header->length) {
236
// invalid data count ?
240
if(tag_header->value) {
241
free(tag_header->value);
244
switch(tag_header->type) {
247
tag_header->value = (char*)malloc((tag_header->length + 1) * sizeof(char));
248
if(!tag_header->value) {
251
char *src_data = (char*)value;
252
char *dst_data = (char*)tag_header->value;
253
for(DWORD i = 0; i < tag_header->length; i++) {
254
dst_data[i] = src_data[i];
256
dst_data[tag_header->length] = '\0';
261
tag_header->value = malloc(tag_header->length * sizeof(BYTE));
262
if(!tag_header->value) {
265
memcpy(tag_header->value, value, tag_header->length);
274
// --------------------------------------------------------------------------
275
// FITAG internal helper functions
276
// --------------------------------------------------------------------------
279
FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type) {
280
static const int format_bytes[] = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4, 4 };
282
return (type < (sizeof(format_bytes)/sizeof(format_bytes[0]))) ?
283
format_bytes[type] : 0;
1
// ==========================================================
2
// Tag manipulation functions
4
// Design and implementation by
5
// - Herv� Drolon <drolon@infonie.fr>
7
// This file is part of FreeImage 3
9
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
10
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
11
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
12
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
13
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
14
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
15
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
16
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
19
// Use at your own risk!
20
// ==========================================================
23
#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
26
#include "FreeImage.h"
27
#include "Utilities.h"
28
#include "FreeImageTag.h"
30
// --------------------------------------------------------------------------
31
// FITAG header definition
32
// --------------------------------------------------------------------------
34
FI_STRUCT (FITAGHEADER) {
35
char *key; // tag field name
36
char *description; // tag description
38
WORD type; // tag data type (see FREE_IMAGE_MDTYPE)
39
DWORD count; // number of components (in 'tag data types' units)
40
DWORD length; // value length in bytes
41
void *value; // tag value
44
// --------------------------------------------------------------------------
45
// FITAG creation / destruction
46
// --------------------------------------------------------------------------
49
FreeImage_CreateTag() {
50
FITAG *tag = (FITAG *)malloc(sizeof(FITAG));
53
unsigned tag_size = sizeof(FITAGHEADER);
54
tag->data = (BYTE *)malloc(tag_size * sizeof(BYTE));
55
if (tag->data != NULL) {
56
memset(tag->data, 0, tag_size);
66
FreeImage_DeleteTag(FITAG *tag) {
68
if (NULL != tag->data) {
69
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
71
free(tag_header->key);
72
free(tag_header->description);
73
free(tag_header->value);
83
FreeImage_CloneTag(FITAG *tag) {
87
FITAG *clone = FreeImage_CreateTag();
88
if(!clone) return NULL;
92
FITAGHEADER *src_tag = (FITAGHEADER *)tag->data;
93
FITAGHEADER *dst_tag = (FITAGHEADER *)clone->data;
96
dst_tag->id = src_tag->id;
99
dst_tag->key = (char*)malloc((strlen(src_tag->key) + 1) * sizeof(char));
101
throw FI_MSG_ERROR_MEMORY;
103
strcpy(dst_tag->key, src_tag->key);
106
if(src_tag->description) {
107
dst_tag->description = (char*)malloc((strlen(src_tag->description) + 1) * sizeof(char));
108
if(!dst_tag->description) {
109
throw FI_MSG_ERROR_MEMORY;
111
strcpy(dst_tag->description, src_tag->description);
114
dst_tag->type = src_tag->type;
116
dst_tag->count = src_tag->count;
118
dst_tag->length = src_tag->length;
120
dst_tag->value = (BYTE*)malloc(src_tag->length * sizeof(BYTE));
121
if(!dst_tag->value) {
122
throw FI_MSG_ERROR_MEMORY;
124
memcpy(dst_tag->value, src_tag->value, src_tag->length);
128
} catch(const char *message) {
129
FreeImage_DeleteTag(clone);
130
FreeImage_OutputMessageProc(FIF_UNKNOWN, message);
135
// --------------------------------------------------------------------------
136
// FITAG getters / setters
137
// --------------------------------------------------------------------------
139
const char * DLL_CALLCONV
140
FreeImage_GetTagKey(FITAG *tag) {
141
return tag ? ((FITAGHEADER *)tag->data)->key : 0;
144
const char * DLL_CALLCONV
145
FreeImage_GetTagDescription(FITAG *tag) {
146
return tag ? ((FITAGHEADER *)tag->data)->description : 0;
150
FreeImage_GetTagID(FITAG *tag) {
151
return tag ? ((FITAGHEADER *)tag->data)->id : 0;
154
FREE_IMAGE_MDTYPE DLL_CALLCONV
155
FreeImage_GetTagType(FITAG *tag) {
156
return tag ? (FREE_IMAGE_MDTYPE)(((FITAGHEADER *)tag->data)->type) : FIDT_NOTYPE;
160
FreeImage_GetTagCount(FITAG *tag) {
161
return tag ? ((FITAGHEADER *)tag->data)->count : 0;
165
FreeImage_GetTagLength(FITAG *tag) {
166
return tag ? ((FITAGHEADER *)tag->data)->length : 0;
169
const void *DLL_CALLCONV
170
FreeImage_GetTagValue(FITAG *tag) {
171
return tag ? ((FITAGHEADER *)tag->data)->value : 0;
175
FreeImage_SetTagKey(FITAG *tag, const char *key) {
177
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
178
if(tag_header->key) free(tag_header->key);
179
tag_header->key = (char*)malloc(strlen(key) + 1);
180
strcpy(tag_header->key, key);
187
FreeImage_SetTagDescription(FITAG *tag, const char *description) {
188
if(tag && description) {
189
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
190
if(tag_header->description) free(tag_header->description);
191
tag_header->description = (char*)malloc(strlen(description) + 1);
192
strcpy(tag_header->description, description);
199
FreeImage_SetTagID(FITAG *tag, WORD id) {
201
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
209
FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type) {
211
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
212
tag_header->type = (WORD)type;
219
FreeImage_SetTagCount(FITAG *tag, DWORD count) {
221
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
222
tag_header->count = count;
229
FreeImage_SetTagLength(FITAG *tag, DWORD length) {
231
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
232
tag_header->length = length;
239
FreeImage_SetTagValue(FITAG *tag, const void *value) {
241
FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
242
// first, check the tag
243
if(tag_header->count * FreeImage_TagDataWidth((FREE_IMAGE_MDTYPE)tag_header->type) != tag_header->length) {
244
// invalid data count ?
248
if(tag_header->value) {
249
free(tag_header->value);
252
switch(tag_header->type) {
255
tag_header->value = (char*)malloc((tag_header->length + 1) * sizeof(char));
256
if(!tag_header->value) {
259
char *src_data = (char*)value;
260
char *dst_data = (char*)tag_header->value;
261
for(DWORD i = 0; i < tag_header->length; i++) {
262
dst_data[i] = src_data[i];
264
dst_data[tag_header->length] = '\0';
269
tag_header->value = malloc(tag_header->length * sizeof(BYTE));
270
if(!tag_header->value) {
273
memcpy(tag_header->value, value, tag_header->length);
282
// --------------------------------------------------------------------------
283
// FITAG internal helper functions
284
// --------------------------------------------------------------------------
287
Given a FREE_IMAGE_MDTYPE, calculate the size of this type in bytes unit
288
@param type Input data type
289
@return Returns the size of the data type, in bytes unit
292
FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type) {
293
static const unsigned format_bytes[] = {
294
0, // FIDT_NOTYPE = 0, // placeholder
295
1, // FIDT_BYTE = 1, // 8-bit unsigned integer
296
1, // FIDT_ASCII = 2, // 8-bit bytes w/ last byte null
297
2, // FIDT_SHORT = 3, // 16-bit unsigned integer
298
4, // FIDT_LONG = 4, // 32-bit unsigned integer
299
8, // FIDT_RATIONAL = 5, // 64-bit unsigned fraction
300
1, // FIDT_SBYTE = 6, // 8-bit signed integer
301
1, // FIDT_UNDEFINED= 7, // 8-bit untyped data
302
2, // FIDT_SSHORT = 8, // 16-bit signed integer
303
4, // FIDT_SLONG = 9, // 32-bit signed integer
304
8, // FIDT_SRATIONAL= 10, // 64-bit signed fraction
305
4, // FIDT_FLOAT = 11, // 32-bit IEEE floating point
306
8, // FIDT_DOUBLE = 12, // 64-bit IEEE floating point
307
4, // FIDT_IFD = 13, // 32-bit unsigned integer (offset)
308
4, // FIDT_PALETTE = 14 // 32-bit RGBQUAD
309
0, // placeholder (15)
310
8, // FIDT_LONG8 = 16, // 64-bit unsigned integer
311
8, // FIDT_SLONG8 = 17, // 64-bit signed integer
312
8 // FIDT_IFD8 = 18 // 64-bit unsigned integer (offset)
315
return (type < (sizeof(format_bytes)/sizeof(format_bytes[0]))) ?
316
format_bytes[type] : 0;