PageRenderTime 28ms CodeModel.GetById 2ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/Metadata/FreeImageTag.cpp

https://bitbucket.org/cabalistic/ogredeps/
C++ | 318 lines | 229 code | 38 blank | 51 comment | 33 complexity | 45295f34b3074de6cf5419888168be5f MD5 | raw file
  1// ==========================================================
  2// Tag manipulation functions
  3//
  4// Design and implementation by
  5// - Hervé Drolon <drolon@infonie.fr>
  6//
  7// This file is part of FreeImage 3
  8//
  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
 17// THIS DISCLAIMER.
 18//
 19// Use at your own risk!
 20// ==========================================================
 21
 22#ifdef _MSC_VER 
 23#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
 24#endif
 25
 26#include "FreeImage.h"
 27#include "Utilities.h"
 28#include "FreeImageTag.h"
 29
 30// --------------------------------------------------------------------------
 31// FITAG header definition
 32// --------------------------------------------------------------------------
 33
 34FI_STRUCT (FITAGHEADER) { 
 35	char *key;			// tag field name
 36	char *description;	// tag description
 37	WORD id;			// tag ID
 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
 42};
 43
 44// --------------------------------------------------------------------------
 45// FITAG creation / destruction
 46// --------------------------------------------------------------------------
 47
 48FITAG * DLL_CALLCONV 
 49FreeImage_CreateTag() {
 50	FITAG *tag = (FITAG *)malloc(sizeof(FITAG));
 51
 52	if (tag != NULL) {
 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);
 57			return tag;
 58		}
 59		free(tag);
 60	}
 61
 62	return NULL;
 63}
 64
 65void DLL_CALLCONV 
 66FreeImage_DeleteTag(FITAG *tag) {
 67	if (NULL != tag) {	
 68		if (NULL != tag->data) {
 69			FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
 70			// delete tag members
 71			free(tag_header->key); 
 72			free(tag_header->description); 
 73			free(tag_header->value);
 74			// delete the tag
 75			free(tag->data);
 76		}
 77		// and the wrapper
 78		free(tag);
 79	}
 80}
 81
 82FITAG * DLL_CALLCONV 
 83FreeImage_CloneTag(FITAG *tag) {
 84	if(!tag) return NULL;
 85
 86	// allocate a new tag
 87	FITAG *clone = FreeImage_CreateTag();
 88	if(!clone) return NULL;
 89
 90	try {
 91		// copy the tag
 92		FITAGHEADER *src_tag = (FITAGHEADER *)tag->data;
 93		FITAGHEADER *dst_tag = (FITAGHEADER *)clone->data;
 94
 95		// tag ID
 96		dst_tag->id = src_tag->id;
 97		// tag key
 98		if(src_tag->key) {
 99			dst_tag->key = (char*)malloc((strlen(src_tag->key) + 1) * sizeof(char));
100			if(!dst_tag->key) {
101				throw FI_MSG_ERROR_MEMORY;
102			}
103			strcpy(dst_tag->key, src_tag->key);
104		}
105		// tag description
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;
110			}
111			strcpy(dst_tag->description, src_tag->description);
112		}
113		// tag data type
114		dst_tag->type = src_tag->type;
115		// tag count
116		dst_tag->count = src_tag->count;
117		// tag length
118		dst_tag->length = src_tag->length;
119		// tag value
120		dst_tag->value = (BYTE*)malloc(src_tag->length * sizeof(BYTE));
121		if(!dst_tag->value) {
122			throw FI_MSG_ERROR_MEMORY;
123		}
124		memcpy(dst_tag->value, src_tag->value, src_tag->length);
125
126		return clone;
127
128	} catch(const char *message) {
129		FreeImage_DeleteTag(clone);
130		FreeImage_OutputMessageProc(FIF_UNKNOWN, message);
131		return NULL;
132	}
133}
134
135// --------------------------------------------------------------------------
136// FITAG getters / setters
137// --------------------------------------------------------------------------
138
139const char * DLL_CALLCONV 
140FreeImage_GetTagKey(FITAG *tag) {
141	return tag ? ((FITAGHEADER *)tag->data)->key : 0;
142}
143
144const char * DLL_CALLCONV 
145FreeImage_GetTagDescription(FITAG *tag) {
146	return tag ? ((FITAGHEADER *)tag->data)->description : 0;
147}
148
149WORD DLL_CALLCONV 
150FreeImage_GetTagID(FITAG *tag) {
151	return tag ? ((FITAGHEADER *)tag->data)->id : 0;
152}
153
154FREE_IMAGE_MDTYPE DLL_CALLCONV 
155FreeImage_GetTagType(FITAG *tag) {
156	return tag ? (FREE_IMAGE_MDTYPE)(((FITAGHEADER *)tag->data)->type) : FIDT_NOTYPE;
157}
158
159DWORD DLL_CALLCONV 
160FreeImage_GetTagCount(FITAG *tag) {
161	return tag ? ((FITAGHEADER *)tag->data)->count : 0;
162}
163
164DWORD DLL_CALLCONV 
165FreeImage_GetTagLength(FITAG *tag) {
166	return tag ? ((FITAGHEADER *)tag->data)->length : 0;
167}
168
169const void *DLL_CALLCONV 
170FreeImage_GetTagValue(FITAG *tag) {
171	return tag ? ((FITAGHEADER *)tag->data)->value : 0;
172}
173
174BOOL DLL_CALLCONV 
175FreeImage_SetTagKey(FITAG *tag, const char *key) {
176	if(tag && 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);
181		return TRUE;
182	}
183	return FALSE;
184}
185
186BOOL DLL_CALLCONV 
187FreeImage_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);
193		return TRUE;
194	}
195	return FALSE;
196}
197
198BOOL DLL_CALLCONV 
199FreeImage_SetTagID(FITAG *tag, WORD id) {
200	if(tag) {
201		FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
202		tag_header->id = id;
203		return TRUE;
204	}
205	return FALSE;
206}
207
208BOOL DLL_CALLCONV 
209FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type) {
210	if(tag) {
211		FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
212		tag_header->type = (WORD)type;
213		return TRUE;
214	}
215	return FALSE;
216}
217
218BOOL DLL_CALLCONV 
219FreeImage_SetTagCount(FITAG *tag, DWORD count) {
220	if(tag) {
221		FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
222		tag_header->count = count;
223		return TRUE;
224	}
225	return FALSE;
226}
227
228BOOL DLL_CALLCONV 
229FreeImage_SetTagLength(FITAG *tag, DWORD length) {
230	if(tag) {
231		FITAGHEADER *tag_header = (FITAGHEADER *)tag->data;
232		tag_header->length = length;
233		return TRUE;
234	}
235	return FALSE;
236}
237
238BOOL DLL_CALLCONV 
239FreeImage_SetTagValue(FITAG *tag, const void *value) {
240	if(tag && 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 ?
245			return FALSE;
246		}
247
248		if(tag_header->value) {
249			free(tag_header->value);
250		}
251
252		switch(tag_header->type) {
253			case FIDT_ASCII:
254			{
255				tag_header->value = (char*)malloc((tag_header->length + 1) * sizeof(char));
256				if(!tag_header->value) {
257					return FALSE;
258				}
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];
263				}
264				dst_data[tag_header->length] = '\0';
265			}
266			break;
267
268			default:
269				tag_header->value = malloc(tag_header->length * sizeof(BYTE));
270				if(!tag_header->value) {
271					return FALSE;
272				}
273				memcpy(tag_header->value, value, tag_header->length);
274				break;
275		}
276		return TRUE;
277	}
278	return FALSE;
279}
280
281
282// --------------------------------------------------------------------------
283// FITAG internal helper functions
284// --------------------------------------------------------------------------
285
286/**
287Given 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
290*/
291unsigned 
292FreeImage_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)
313	};
314
315	  return (type < (sizeof(format_bytes)/sizeof(format_bytes[0]))) ?
316		  format_bytes[type] : 0;
317}
318