Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 701 lines (536 sloc) 14.466 kB
faa9b3e Egads
Tony Cook authored
1 /*
2 =head1 NAME
3
4 tags.c - functions for manipulating an images tags list
5
6 =head1 SYNOPSIS
7
8 i_img_tags tags;
9 i_tags_new(&tags);
10 i_tags_destroy(&tags);
11 i_tags_addn(&tags, "name", code, idata);
12 i_tags_add(&tags, "name", code, data, data_size, idata);
13 if (i_tags_find(&tags, name, start, &entry)) { found }
14 if (i_tags_findn(&tags, code, start, &entry)) { found }
15 i_tags_delete(&tags, index);
16 count = i_tags_delbyname(tags, name);
17 count = i_tags_delbycode(tags, code);
2e41e30 - the i_xres and i_yres tags are now stored in a resolution similar
Tony Cook authored
18 if (i_tags_get_float(&tags, name, code, &float_value)) { found }
19 i_tags_set_float(&tags, name, code, value);
20 i_tags_set_float2(&tags, name, code, value, sig_digits);
21 i_tags_get_int(&tags, name, code, &int_value);
faa9b3e Egads
Tony Cook authored
22
23 =head1 DESCRIPTION
24
25 Provides functions which give write access to the tags list of an image.
26
27 For read access directly access the fields (do not write any fields
28 directly).
29
30 A tag is represented by an i_img_tag structure:
31
32 typedef enum {
33 itt_double,
34 iit_text
35 } i_tag_type;
36
37 typedef struct {
38 char *name; // name of a given tag, might be NULL
39 int code; // number of a given tag, -1 if it has no meaning
40 char *data; // value of a given tag if it's not an int, may be NULL
41 int size; // size of the data
42 int idata; // value of a given tag if data is NULL
43 } i_img_tag;
44
45
46 =over
47
48 =cut
49 */
50
92bda63 - start of external Imager API access:
Tony Cook authored
51 #include "imager.h"
faa9b3e Egads
Tony Cook authored
52 #include <string.h>
53 #include <stdlib.h>
97c4eff merge write to gif tags updates
Tony Cook authored
54 #include <errno.h>
55 #include <limits.h>
faa9b3e Egads
Tony Cook authored
56
57 /* useful for debugging */
58 void i_tags_print(i_img_tags *tags);
59
60 /*
61 =item i_tags_new(i_img_tags *tags)
62
92bda63 - start of external Imager API access:
Tony Cook authored
63 =category Tags
64
faa9b3e Egads
Tony Cook authored
65 Initialize a tags structure. Should not be used if the tags structure
66 has been previously used.
67
92bda63 - start of external Imager API access:
Tony Cook authored
68 This should be called tags member of an i_img object on creation (in
69 i_img_*_new() functions).
70
faa9b3e Egads
Tony Cook authored
71 To destroy the contents use i_tags_destroy()
72
73 =cut
74 */
75
76 void i_tags_new(i_img_tags *tags) {
77 tags->count = tags->alloc = 0;
78 tags->tags = NULL;
79 }
80
81 /*
82 =item i_tags_addn(i_img_tags *tags, char *name, int code, int idata)
83
84 Adds a tag that has an integer value. A simple wrapper around i_tags_add().
85
6cfee9d API documentation (mostly)
Tony Cook authored
86 Use i_tags_setn() instead, this function may be removed in the future.
faa9b3e Egads
Tony Cook authored
87
88 Returns non-zero on success.
89
90 =cut
91 */
92
97c4eff merge write to gif tags updates
Tony Cook authored
93 int i_tags_addn(i_img_tags *tags, char const *name, int code, int idata) {
faa9b3e Egads
Tony Cook authored
94 return i_tags_add(tags, name, code, NULL, 0, idata);
95 }
96
97 /*
98 =item i_tags_add(i_img_tags *tags, char *name, int code, char *data, int size, i_tag_type type, int idata)
99
100 Adds a tag to the tags list.
101
6cfee9d API documentation (mostly)
Tony Cook authored
102 Use i_tags_set() instead, this function may be removed in the future.
faa9b3e Egads
Tony Cook authored
103
104 Returns non-zero on success.
105
106 =cut
107 */
108
97c4eff merge write to gif tags updates
Tony Cook authored
109 int i_tags_add(i_img_tags *tags, char const *name, int code, char const *data,
110 int size, int idata) {
faa9b3e Egads
Tony Cook authored
111 i_img_tag work = {0};
97c4eff merge write to gif tags updates
Tony Cook authored
112 /*printf("i_tags_add(tags %p [count %d], name %s, code %d, data %p, size %d, idata %d)\n",
113 tags, tags->count, name, code, data, size, idata);*/
faa9b3e Egads
Tony Cook authored
114 if (tags->tags == NULL) {
115 int alloc = 10;
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
116 tags->tags = mymalloc(sizeof(i_img_tag) * alloc);
faa9b3e Egads
Tony Cook authored
117 if (!tags->tags)
118 return 0;
119 tags->alloc = alloc;
120 }
121 else if (tags->count == tags->alloc) {
122 int newalloc = tags->alloc + 10;
7f882a0 Added an Imager::log_entry() function and some extra logging
Arnar Mar Hrafnkelsson authored
123 void *newtags = myrealloc(tags->tags, sizeof(i_img_tag) * newalloc);
faa9b3e Egads
Tony Cook authored
124 if (!newtags) {
125 return 0;
126 }
127 tags->tags = newtags;
128 tags->alloc = newalloc;
129 }
130 if (name) {
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
131 work.name = mymalloc(strlen(name)+1);
faa9b3e Egads
Tony Cook authored
132 if (!work.name)
133 return 0;
134 strcpy(work.name, name);
135 }
136 if (data) {
403946c - the BMP reader now validates the bfOffBits value from the BMP header
Tony Cook authored
137 if (size == -1)
138 size = strlen(data);
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
139 work.data = mymalloc(size+1);
faa9b3e Egads
Tony Cook authored
140 if (!work.data) {
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
141 if (work.name) myfree(work.name);
faa9b3e Egads
Tony Cook authored
142 return 0;
143 }
144 memcpy(work.data, data, size);
145 work.data[size] = '\0'; /* convenience */
146 work.size = size;
147 }
148 work.code = code;
149 work.idata = idata;
150 tags->tags[tags->count++] = work;
151
97c4eff merge write to gif tags updates
Tony Cook authored
152 /*i_tags_print(tags);*/
153
faa9b3e Egads
Tony Cook authored
154 return 1;
155 }
156
92bda63 - start of external Imager API access:
Tony Cook authored
157 /*
158 =item i_tags_destroy(tags)
159
160 =category Tags
161
162 Destroys the given tags structure. Called by i_img_destroy().
163
164 =cut
165 */
166
faa9b3e Egads
Tony Cook authored
167 void i_tags_destroy(i_img_tags *tags) {
168 if (tags->tags) {
169 int i;
170 for (i = 0; i < tags->count; ++i) {
171 if (tags->tags[i].name)
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
172 myfree(tags->tags[i].name);
faa9b3e Egads
Tony Cook authored
173 if (tags->tags[i].data)
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
174 myfree(tags->tags[i].data);
faa9b3e Egads
Tony Cook authored
175 }
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
176 myfree(tags->tags);
faa9b3e Egads
Tony Cook authored
177 }
178 }
179
92bda63 - start of external Imager API access:
Tony Cook authored
180 /*
181 =item i_tags_find(tags, name, start, &entry)
182
183 =category Tags
184
7468f3f - fix spelling errors patched by Debian (please report the issues you
Tony Cook authored
185 Searches for a tag of the given I<name> starting from index I<start>.
92bda63 - start of external Imager API access:
Tony Cook authored
186
187 On success returns true and sets *I<entry>.
188
189 On failure returns false.
190
191 =cut
192 */
193
97c4eff merge write to gif tags updates
Tony Cook authored
194 int i_tags_find(i_img_tags *tags, char const *name, int start, int *entry) {
faa9b3e Egads
Tony Cook authored
195 if (tags->tags) {
196 while (start < tags->count) {
197 if (tags->tags[start].name && strcmp(name, tags->tags[start].name) == 0) {
198 *entry = start;
199 return 1;
200 }
201 ++start;
202 }
203 }
204 return 0;
205 }
206
92bda63 - start of external Imager API access:
Tony Cook authored
207 /*
208 =item i_tags_findn(tags, code, start, &entry)
209
210 =category Tags
211
5715f7c huge spelling update and spell checking patch
Tony Cook authored
212 Searches for a tag of the given I<code> starting from index I<start>.
92bda63 - start of external Imager API access:
Tony Cook authored
213
214 On success returns true and sets *I<entry>.
215
216 On failure returns false.
217
218 =cut
219 */
220
faa9b3e Egads
Tony Cook authored
221 int i_tags_findn(i_img_tags *tags, int code, int start, int *entry) {
222 if (tags->tags) {
223 while (start < tags->count) {
224 if (tags->tags[start].code == code) {
225 *entry = start;
226 return 1;
227 }
228 ++start;
229 }
230 }
231 return 0;
232 }
233
92bda63 - start of external Imager API access:
Tony Cook authored
234 /*
235 =item i_tags_delete(tags, index)
236
237 =category Tags
238
239 Delete a tag by index.
240
241 Returns true on success.
242
243 =cut
244 */
faa9b3e Egads
Tony Cook authored
245 int i_tags_delete(i_img_tags *tags, int entry) {
97c4eff merge write to gif tags updates
Tony Cook authored
246 /*printf("i_tags_delete(tags %p [count %d], entry %d)\n",
247 tags, tags->count, entry);*/
faa9b3e Egads
Tony Cook authored
248 if (tags->tags && entry >= 0 && entry < tags->count) {
249 i_img_tag old = tags->tags[entry];
250 memmove(tags->tags+entry, tags->tags+entry+1,
97c4eff merge write to gif tags updates
Tony Cook authored
251 (tags->count-entry-1) * sizeof(i_img_tag));
faa9b3e Egads
Tony Cook authored
252 if (old.name)
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
253 myfree(old.name);
faa9b3e Egads
Tony Cook authored
254 if (old.data)
4dfa552 Added io_buffer for reading from scalars. Also added test cases. Added
Arnar Mar Hrafnkelsson authored
255 myfree(old.data);
faa9b3e Egads
Tony Cook authored
256 --tags->count;
97c4eff merge write to gif tags updates
Tony Cook authored
257
faa9b3e Egads
Tony Cook authored
258 return 1;
259 }
260 return 0;
261 }
262
92bda63 - start of external Imager API access:
Tony Cook authored
263 /*
264 =item i_tags_delbyname(tags, name)
265
266 =category Tags
267
268 Delete any tags with the given name.
269
270 Returns the number of tags deleted.
271
272 =cut
273 */
274
97c4eff merge write to gif tags updates
Tony Cook authored
275 int i_tags_delbyname(i_img_tags *tags, char const *name) {
faa9b3e Egads
Tony Cook authored
276 int count = 0;
277 int i;
97c4eff merge write to gif tags updates
Tony Cook authored
278 /*printf("i_tags_delbyname(tags %p [count %d], name %s)\n",
279 tags, tags->count, name);*/
faa9b3e Egads
Tony Cook authored
280 if (tags->tags) {
281 for (i = tags->count-1; i >= 0; --i) {
282 if (tags->tags[i].name && strcmp(name, tags->tags[i].name) == 0) {
283 ++count;
284 i_tags_delete(tags, i);
285 }
286 }
287 }
97c4eff merge write to gif tags updates
Tony Cook authored
288 /*i_tags_print(tags);*/
289
faa9b3e Egads
Tony Cook authored
290 return count;
291 }
292
92bda63 - start of external Imager API access:
Tony Cook authored
293 /*
294 =item i_tags_delbycode(tags, code)
295
296 =category Tags
297
298 Delete any tags with the given code.
299
300 Returns the number of tags deleted.
301
302 =cut
303 */
304
faa9b3e Egads
Tony Cook authored
305 int i_tags_delbycode(i_img_tags *tags, int code) {
306 int count = 0;
307 int i;
308 if (tags->tags) {
309 for (i = tags->count-1; i >= 0; --i) {
310 if (tags->tags[i].code == code) {
311 ++count;
312 i_tags_delete(tags, i);
313 }
314 }
315 }
316 return count;
317 }
318
92bda63 - start of external Imager API access:
Tony Cook authored
319 /*
320 =item i_tags_get_float(tags, name, code, value)
321
322 =category Tags
323
324 Retrieves a tag as a floating point value.
325
326 If the tag has a string value then that is parsed as a floating point
327 number, otherwise the integer value of the tag is used.
328
329 On success sets *I<value> and returns true.
330
331 On failure returns false.
332
333 =cut
334 */
335
97c4eff merge write to gif tags updates
Tony Cook authored
336 int i_tags_get_float(i_img_tags *tags, char const *name, int code,
337 double *value) {
faa9b3e Egads
Tony Cook authored
338 int index;
339 i_img_tag *entry;
340
341 if (name) {
342 if (!i_tags_find(tags, name, 0, &index))
343 return 0;
344 }
345 else {
346 if (!i_tags_findn(tags, code, 0, &index))
347 return 0;
348 }
349 entry = tags->tags+index;
350 if (entry->data)
351 *value = atof(entry->data);
352 else
353 *value = entry->idata;
354
355 return 1;
356 }
357
92bda63 - start of external Imager API access:
Tony Cook authored
358 /*
359 =item i_tags_set_float(tags, name, code, value)
360
361 =category Tags
362
363 Equivalent to i_tags_set_float2(tags, name, code, value, 30).
364
365 =cut
366 */
367
97c4eff merge write to gif tags updates
Tony Cook authored
368 int i_tags_set_float(i_img_tags *tags, char const *name, int code,
369 double value) {
2e41e30 - the i_xres and i_yres tags are now stored in a resolution similar
Tony Cook authored
370 return i_tags_set_float2(tags, name, code, value, 30);
371 }
372
373 /*
374 =item i_tags_set_float2(tags, name, code, value, places)
375
92bda63 - start of external Imager API access:
Tony Cook authored
376 =category Tags
377
2e41e30 - the i_xres and i_yres tags are now stored in a resolution similar
Tony Cook authored
378 Sets the tag with the given name and code to the given floating point
379 value.
380
381 Since tags are strings or ints, we convert the value to a string before
382 storage at the precision specified by C<places>.
383
384 =cut
385 */
386
387 int i_tags_set_float2(i_img_tags *tags, char const *name, int code,
388 double value, int places) {
faa9b3e Egads
Tony Cook authored
389 char temp[40];
390
2e41e30 - the i_xres and i_yres tags are now stored in a resolution similar
Tony Cook authored
391 if (places < 0)
392 places = 30;
393 else if (places > 30)
394 places = 30;
395
396 sprintf(temp, "%.*g", places, value);
faa9b3e Egads
Tony Cook authored
397 if (name)
398 i_tags_delbyname(tags, name);
399 else
400 i_tags_delbycode(tags, code);
401
402 return i_tags_add(tags, name, code, temp, strlen(temp), 0);
403 }
404
92bda63 - start of external Imager API access:
Tony Cook authored
405 /*
406 =item i_tags_get_int(tags, name, code, &value)
407
408 =category Tags
409
410 Retrieve a tag specified by name or code as an integer.
411
743e98e fix documentation nit
Tony Cook authored
412 On success sets the int *I<value> to the integer and returns true.
92bda63 - start of external Imager API access:
Tony Cook authored
413
414 On failure returns false.
415
416 =cut
417 */
418
97c4eff merge write to gif tags updates
Tony Cook authored
419 int i_tags_get_int(i_img_tags *tags, char const *name, int code, int *value) {
faa9b3e Egads
Tony Cook authored
420 int index;
421 i_img_tag *entry;
422
423 if (name) {
424 if (!i_tags_find(tags, name, 0, &index))
425 return 0;
426 }
427 else {
428 if (!i_tags_findn(tags, code, 0, &index))
429 return 0;
430 }
431 entry = tags->tags+index;
432 if (entry->data)
433 *value = atoi(entry->data);
434 else
435 *value = entry->idata;
436
437 return 1;
438 }
439
97c4eff merge write to gif tags updates
Tony Cook authored
440 static int parse_long(char *data, char **end, long *out) {
441 long result;
442 int savederr = errno;
443 char *myend;
444
445 errno = 0;
446 result = strtol(data, &myend, 10);
af070d9 - eliminate many -Wall warnings
Tony Cook authored
447 if (((result == LONG_MIN || result == LONG_MAX) && errno == ERANGE)
97c4eff merge write to gif tags updates
Tony Cook authored
448 || myend == data) {
a659442 - eliminate unused variables and static functions
Tony Cook authored
449 errno = savederr;
97c4eff merge write to gif tags updates
Tony Cook authored
450 return 0;
451 }
452
a659442 - eliminate unused variables and static functions
Tony Cook authored
453 errno = savederr;
97c4eff merge write to gif tags updates
Tony Cook authored
454 *out = result;
455 *end = myend;
456
457 return 1;
458 }
459
460 /* parse a comma-separated list of integers
461 returns when it has maxcount numbers, finds a non-comma after a number
462 or can't parse a number
463 if it can't parse a number after a comma, that's considered an error
464 */
465 static int parse_long_list(char *data, char **end, int maxcount, long *out) {
466 int i;
467
26fd367 various changes from trying to build on testdrive
Tony Cook authored
468 i = 0;
97c4eff merge write to gif tags updates
Tony Cook authored
469 while (i < maxcount-1) {
470 if (!parse_long(data, &data, out))
471 return 0;
472 out++;
473 i++;
474 if (*data != ',')
475 return i;
476 ++data;
477 }
478 if (!parse_long(data, &data, out))
479 return 0;
480 ++i;
481 *end = data;
482 return i;
483 }
484
485 /* parse "color(red,green,blue,alpha)" */
486 static int parse_color(char *data, char **end, i_color *value) {
487 long n[4];
488 int count, i;
489
490 if (memcmp(data, "color(", 6))
491 return 0; /* not a color */
492 data += 6;
493 count = parse_long_list(data, &data, 4, n);
494 if (count < 3)
495 return 0;
496 for (i = 0; i < count; ++i)
497 value->channel[i] = n[i];
498 if (count < 4)
499 value->channel[3] = 255;
500
501 return 1;
502 }
503
92bda63 - start of external Imager API access:
Tony Cook authored
504 /*
505 =item i_tags_get_color(tags, name, code, &value)
506
507 =category Tags
508
509 Retrieve a tag specified by name or code as color.
510
511 On success sets the i_color *I<value> to the color and returns true.
512
513 On failure returns false.
514
515 =cut
516 */
517
97c4eff merge write to gif tags updates
Tony Cook authored
518 int i_tags_get_color(i_img_tags *tags, char const *name, int code,
519 i_color *value) {
520 int index;
521 i_img_tag *entry;
522 char *end;
523
524 if (name) {
525 if (!i_tags_find(tags, name, 0, &index))
526 return 0;
527 }
528 else {
529 if (!i_tags_findn(tags, code, 0, &index))
530 return 0;
531 }
532 entry = tags->tags+index;
533 if (!entry->data)
534 return 0;
535
536 if (!parse_color(entry->data, &end, value))
537 return 0;
538
539 /* for now we're sloppy about the end */
540
541 return 1;
542 }
543
92bda63 - start of external Imager API access:
Tony Cook authored
544 /*
545 =item i_tags_set_color(tags, name, code, &value)
546
547 =category Tags
548
549 Stores the given color as a tag with the given name and code.
550
551 =cut
552 */
553
97c4eff merge write to gif tags updates
Tony Cook authored
554 int i_tags_set_color(i_img_tags *tags, char const *name, int code,
555 i_color const *value) {
556 char temp[80];
557
558 sprintf(temp, "color(%d,%d,%d,%d)", value->channel[0], value->channel[1],
559 value->channel[2], value->channel[3]);
560 if (name)
561 i_tags_delbyname(tags, name);
562 else
563 i_tags_delbycode(tags, code);
564
565 return i_tags_add(tags, name, code, temp, strlen(temp), 0);
566 }
567
92bda63 - start of external Imager API access:
Tony Cook authored
568 /*
569 =item i_tags_get_string(tags, name, code, value, value_size)
570
571 =category Tags
572
573 Retrieves a tag by name or code as a string.
574
575 On success copies the string to value for a max of value_size and
576 returns true.
577
578 On failure returns false.
579
580 value_size must be at least large enough for a string representation
581 of an integer.
582
5715f7c huge spelling update and spell checking patch
Tony Cook authored
583 The copied value is always C<NUL> terminated.
92bda63 - start of external Imager API access:
Tony Cook authored
584
585 =cut
586 */
587
97c4eff merge write to gif tags updates
Tony Cook authored
588 int i_tags_get_string(i_img_tags *tags, char const *name, int code,
faa9b3e Egads
Tony Cook authored
589 char *value, size_t value_size) {
590 int index;
591 i_img_tag *entry;
592
593 if (name) {
594 if (!i_tags_find(tags, name, 0, &index))
595 return 0;
596 }
597 else {
598 if (!i_tags_findn(tags, code, 0, &index))
599 return 0;
600 }
601 entry = tags->tags+index;
602 if (entry->data) {
603 size_t cpsize = value_size < entry->size ? value_size : entry->size;
604 memcpy(value, entry->data, cpsize);
605 if (cpsize == value_size)
606 --cpsize;
607 value[cpsize] = '\0';
608 }
609 else {
241defe - the internal i_tags_get_string() function now acts correctly for
Tony Cook authored
610 sprintf(value, "%d", entry->idata);
faa9b3e Egads
Tony Cook authored
611 }
612
613 return 1;
614 }
615
92bda63 - start of external Imager API access:
Tony Cook authored
616 /*
617 =item i_tags_set(tags, name, data, size)
6cfee9d API documentation (mostly)
Tony Cook authored
618 =synopsis i_tags_set(&img->tags, "i_comment", -1);
92bda63 - start of external Imager API access:
Tony Cook authored
619 =category Tags
620
621 Sets the given tag to the string I<data>
622
6cfee9d API documentation (mostly)
Tony Cook authored
623 If size is -1 then the strlen(I<data>) bytes are stored.
624
625 Even on failure, if an existing tag I<name> exists, it will be
626 removed.
627
92bda63 - start of external Imager API access:
Tony Cook authored
628 =cut
629 */
630
631 int
632 i_tags_set(i_img_tags *tags, char const *name, char const *data, int size) {
633 i_tags_delbyname(tags, name);
634
635 return i_tags_add(tags, name, 0, data, size, 0);
636 }
637
638 /*
5715f7c huge spelling update and spell checking patch
Tony Cook authored
639 =item i_tags_setn(C<tags>, C<name>, C<idata>)
6cfee9d API documentation (mostly)
Tony Cook authored
640 =synopsis i_tags_setn(&img->tags, "i_xres", 204);
641 =synopsis i_tags_setn(&img->tags, "i_yres", 196);
92bda63 - start of external Imager API access:
Tony Cook authored
642 =category Tags
643
5715f7c huge spelling update and spell checking patch
Tony Cook authored
644 Sets the given tag to the integer C<idata>
92bda63 - start of external Imager API access:
Tony Cook authored
645
5715f7c huge spelling update and spell checking patch
Tony Cook authored
646 Even on failure, if an existing tag C<name> exists, it will be
6cfee9d API documentation (mostly)
Tony Cook authored
647 removed.
648
92bda63 - start of external Imager API access:
Tony Cook authored
649 =cut
650 */
651
652 int
653 i_tags_setn(i_img_tags *tags, char const *name, int idata) {
654 i_tags_delbyname(tags, name);
655
656 return i_tags_addn(tags, name, 0, idata);
657 }
658
faa9b3e Egads
Tony Cook authored
659 void i_tags_print(i_img_tags *tags) {
660 int i;
661 printf("Alloc %d\n", tags->alloc);
662 printf("Count %d\n", tags->count);
663 for (i = 0; i < tags->count; ++i) {
664 i_img_tag *tag = tags->tags + i;
665 printf("Tag %d\n", i);
666 if (tag->name)
97c4eff merge write to gif tags updates
Tony Cook authored
667 printf(" Name : %s (%p)\n", tag->name, tag->name);
faa9b3e Egads
Tony Cook authored
668 printf(" Code : %d\n", tag->code);
669 if (tag->data) {
670 int pos;
97c4eff merge write to gif tags updates
Tony Cook authored
671 printf(" Data : %d (%p) => '", tag->size, tag->data);
faa9b3e Egads
Tony Cook authored
672 for (pos = 0; pos < tag->size; ++pos) {
673 if (tag->data[pos] == '\\' || tag->data[pos] == '\'') {
674 putchar('\\');
675 putchar(tag->data[pos]);
676 }
677 else if (tag->data[pos] < ' ' || tag->data[pos] >= '\x7E')
678 printf("\\x%02X", tag->data[pos]);
679 else
680 putchar(tag->data[pos]);
681 }
682 printf("'\n");
683 printf(" Idata: %d\n", tag->idata);
684 }
685 }
686 }
b8c2033 Fixed i_transform2() so malloc(0) doesn't happen. Also corrected pod…
Arnar Mar Hrafnkelsson authored
687
688 /*
689 =back
690
691 =head1 AUTHOR
692
693 Tony Cook <tony@develop-help.com>
694
695 =head1 SEE ALSO
696
697 Imager(3)
698
699 =cut
700 */
Something went wrong with that request. Please try again.