1
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "tiio_tzp.h"
8
9 extern "C" {
10 #include "../tif/tifimage/tiff.h"
11 #include "../tif/tifimage/tiffio.h"
12 }
13
14 //#include "toonz.h"
15 //#include "tmsg.h"
16 //#include "file.h"
17 //#include "img.h"
18 //#include "tiff.h"
19 //#include "tiffio.h"
20 //#include "tim.h"
21 //#include "history.h"
22 //#include "../infoRegionP.h"
23 //#include "version.h"
24 //#include "machine.h"
25 //#include "tenv.h"
26 //#include "ImageP/img_security.h"
27
28 #define ICON_WIDTH 100
29 #define ICON_HEIGHT 90
30
31 #define TBOOL int
32 #define FALSE 0
33 #define TRUE 1
34
35 #define UCHAR unsigned char
36 #define USHORT unsigned short
37 #define ULONG unsigned long
38 #define UINT unsigned int
39
40 #define CASE \
41 break; \
42 case
43 #define __OR case
44 #define DEFAULT \
45 break; \
46 default
47
48 #ifndef MAXINT
49 #define MAXINT ((int)((~0U) >> 1))
50 #endif
51
52 #define NOT_LESS_THAN(A, B)
53 typedef struct { UCHAR r, g, b, m; } LPIXEL;
54
55 #define TMALLOC(A, C) A = malloc(C * sizeof(A[0]));
56 #define TFREE(A) free(A);
57 #define NIL 0
58
59 typedef struct {
60 int x1, y1, x2, y2;
61 int x_offset, y_offset; /* offset all'interno della regione */
62 int xsize, ysize; /* dimensioni della regione */
63 int scanNrow, scanNcol; /* righe e col. dell'immagine da scan. */
64 int startScanRow, startScanCol; /* offset nell'immagine da scandire */
65 int step; /* fattore di scale */
66 int lx_in, ly_in; /* dimensioni immag. da scandire */
67 int verso_x, verso_y; /* verso di scrittura nel buffer dest. */
68 int buf_inc; /* incremento tra due pix. consecutivi */
69 int sxpix, expix, sypix, eypix; /* pixel estremi del buffer di input */
70 } INFO_REGION;
71
72 typedef struct {
73 /*UCHAR tone_offs; sempre 0 */
74 UCHAR tone_bits;
75 UCHAR color_offs;
76 UCHAR color_bits;
77 UCHAR pencil_offs;
78 UCHAR pencil_bits;
79 USHORT offset_mask; // fa allo stesso tempo sia da offset che da maschera
80 USHORT default_val; // da utilizzare, p.es., per pixel fuori dall'immagine
81 short n_tones;
82 short n_colors;
83 short n_pencils;
84 } TCM_INFO;
85
86 static const TCM_INFO Tcm_old_default_info = {
87 /*0,*/ 4, 4, 5, 9, 2, 0x0800, 0x080f, 16, 32, 4};
88 static const TCM_INFO Tcm_new_default_info = {
89 /*0,*/ 4, 4, 7, 11, 5, 0x0000, 0x000f, 16, 128, 32};
90 static const TCM_INFO Tcm_24_default_info = {
91 /*0,*/ 8, 8, 8, 16, 8, 0x0000, 0x00ff, 256, 256, 256};
92
93 #define TCM_TONE_MASK(TCM) ((1U << (TCM).tone_bits) - 1U)
94 #define TCM_COLOR_MASK(TCM) \
95 (((1U << (TCM).color_bits) - 1U) << (TCM).color_offs)
96 #define TCM_PENCIL_MASK(TCM) \
97 (((1U << (TCM).pencil_bits) - 1U) << (TCM).pencil_offs)
98
99 #define TCM_COLOR_INDEX(TCM, ID) \
100 ((ID) << (TCM).color_offs | ((TCM).n_tones - 1) | (TCM).offset_mask)
101 #define TCM_PENCIL_INDEX(TCM, ID) \
102 ((ID) << (TCM).pencil_offs | (TCM).offset_mask)
103
104 #define TCM_INDEX_IS_COLOR_ONLY(TCM, INDEX) \
105 (((INDEX)&TCM_TONE_MASK(TCM)) == TCM_TONE_MASK(TCM))
106 #define TCM_INDEX_IS_PENCIL_ONLY(TCM, INDEX) (((INDEX)&TCM_TONE_MASK(TCM)) == 0)
107
108 #define TCM_COLOR_ID(TCM, INDEX) \
109 ((int)(((INDEX) >> (TCM).color_offs) & ((1U << (TCM).color_bits) - 1U)))
110 #define TCM_PENCIL_ID(TCM, INDEX) \
111 ((int)(((INDEX) >> (TCM).pencil_offs) & ((1U << (TCM).pencil_bits) - 1U)))
112
113 #define TCM_MIN_CMAP_BUFFER_SIZE(TCM) \
114 ((((TCM).n_pencils - 1) << (TCM).pencil_offs | \
115 ((TCM).n_colors - 1) << (TCM).color_offs | (TCM).n_tones - 1) + \
116 1)
117
118 #define TCM_MIN_CMAP_COLBUFFER_SIZE(TCM) ((TCM).n_colors * (TCM).n_tones)
119
120 #define TCM_MIN_CMAP_PENBUFFER_SIZE(TCM) ((TCM).n_pencils * (TCM).n_tones)
121
122 #define TCM_CMAP_BUFFER_SIZE(TCM) \
123 (1 << ((TCM).pencil_bits + (TCM).color_bits + (TCM).tone_bits))
124
125 #define TCM_CMAP_COLBUFFER_SIZE(TCM) (1 << ((TCM).color_bits + (TCM).tone_bits))
126
127 #define TCM_CMAP_PENBUFFER_SIZE(TCM) \
128 (1 << ((TCM).pencil_bits + (TCM).tone_bits))
129
130 static int Next_img_read_with_extra = FALSE;
131 static int Read_with_extra = FALSE;
132 #define SET_READ_WITH_EXTRA \
133 { \
134 Read_with_extra = Next_img_read_with_extra; \
135 Next_img_read_with_extra = FALSE; \
136 }
137
138 typedef struct {
139 USHORT bits_per_sample, samples_per_pixel, photometric;
140 int xsize, ysize, xSBsize, ySBsize, x0, y0;
141 double x_dpi, y_dpi;
142 double h_pos; // in pixel, mentre TIFFTAG_XPOSITION e' in RESUNITS
143 UCHAR extra_mask;
144 TBOOL edu_file;
145 } TZUP_FIELDS;
146
147 // Tipi di IMAGE
148 enum img_type {
149 IMG_NONE,
150 CMAPPED, /* fa riferimento a una color-map */
151 CMAPPED24, /* 3 x 8 bit (ink, paint, ramp) + 8 bit extra (nel MSB) */
152 RGB, /* ogni pixel e' una terna red-green-blue - 8bit per canale */
153 RGB64, /* ogni pixel e' una terna red-green-blue - 16bit per canale */
154 GR8, /* a toni di grigio */
155 CMAP /* color map */
156 };
157
158 /* pixel-map */
159 struct s_pixmap {
160 USHORT *buffer;
161 UCHAR *extra; /* patches etc. */
162 UCHAR extra_mask; /* bits extra usati in buffer (CMAPPED24) o in extra */
163 int xsize, ysize;
164 int xSBsize, ySBsize, xD, yD; /* savebox */
165 double x_dpi, y_dpi;
166 double h_pos; /* in pixel */
167 };
168
169 /* color-map */
170 struct s_cmap {
171 char *name; /* riferimento a CMAP esterna */
172 LPIXEL *buffer; /* buffer della colormap (premoltiplicata) */
173 LPIXEL *penbuffer; /* buffer della componente di pencil per > 16 bits */
174 LPIXEL *colbuffer; /* buffer della componente di color per > 16 bits */
175 LPIXEL *pencil; /* i colori non premoltiplicati */
176 LPIXEL *color; /* tanti quanto dicono info.n_pencils e n_colors */
177 TCM_INFO info; /* vedi tcm.h */
178 void *names; /* nomi dei colori, gestiti da colorsdb */
179
180 /* seguono i campi che andrebbero eliminati perche' doppioni */
181 int offset; /* == info.offset_mask */
182 int pencil_n, color_n; /* == info.n_pencils e n_colors */
183 };
184
185 /* Enum per l'identificazione dell' algoritmo di riduzione dei colori */
186
187 typedef enum { CM_NONE = -1, CM_STANDARD, CM_CUSTOM } IMG_CM_ALGORITHM;
188
189 /* Struttura per le modalita' di scrittura dei formati di file supportati */
190
191 typedef struct {
192 char rgb_is_compressed;
193 char rgb_write_matte;
194 char rgb_64_bits;
195 char rgb_colorstyle; /* full color or greyscale */
196 char tga_bytes_per_pixel;
197 char tga_is_colormap;
198 char tga_is_compressed;
199
200 /*
201 * Microsoft Windows Bitmap (BMP and DIB)
202 *
203 * | compression | colorstyle | numcolors |
204 * ---------------------------------------------------------------
205 * BLack & White | 0 | 0 | 2 |
206 * ----------------------------------------------------------------
207 * 16 Grey Tones | 0 | GR8 | 16 |
208 * ---------------------------------------------------------------
209 * 16 Grey Tones Comp. | 1 | GR8 | 16 |
210 * ---------------------------------------------------------------
211 * 256 Grey Tones | 0 | GR8 | 256 |
212 * ---------------------------------------------------------------
213 * 256 Grey Tones Comp. | 1 | GR8 | 256 |
214 * ---------------------------------------------------------------
215 * 16 Color Mapped | 0 | CMAPPED | 16 |
216 * ---------------------------------------------------------------
217 * 16 Color Mapped Comp.| 1 | CMAPPED | 16 |
218 * ---------------------------------------------------------------
219 * 256 Color Mapped | 0 | CMAPPED | 256 |
220 * ---------------------------------------------------------------
221 * 256 Color Mapped Comp.| 1 | CMAPPED | 256 |
222 * ---------------------------------------------------------------
223 * Full Color | 0 | RGB | 0 |
224 * ---------------------------------------------------------------
225 *
226 */
227 unsigned short bmp_compression;
228 unsigned short bmp_colorstyle;
229 unsigned short bmp_numcolors;
230
231 /*---------------------------------------------------------------*/
232
233 unsigned int jpg_quality;
234 unsigned int jpg_smoothing;
235 unsigned int jpg_components;
236
237 /*---------------------------------------------------------------*/
238
239 unsigned short tif_compression;
240 unsigned short tif_orientation;
241 unsigned short tif_photometric;
242 unsigned short tif_bits_per_sample;
243 unsigned short tif_samples_per_pixel;
244
245 /*---------------------------------------------------------------*/
246
247 IMG_CM_ALGORITHM cm_algorithm;
248
249 /*---------------------------------------------------------------*/
250
251 /*TNZMOVIE_QUALITY pct_quality;
252 TNZMOVIE_COMPRESSION pct_compression;
253 */
254 /*---------------------------------------------------------------*/
255 /*
256 TNZMOVIE_QUALITY mov_quality;
257 TNZMOVIE_COMPRESSION mov_compression;
258 */
259 int avi_bpp;
260 char *avi_compression;
261 } IMG_IO_SETTINGS;
262
263 /* Struttura IMAGE */
264 typedef struct s_image {
265 enum img_type type;
266 char *filename;
267 char *history;
268 struct s_pixmap icon; /* Icon */
269 struct s_cmap cmap; /* Colormap */
270 struct s_pixmap pixmap; /* Pixel Map */
271 IMG_IO_SETTINGS io_settings;
272 } IMAGE;
273
274 extern int Silent_tiff_print_error;
275 extern int Tiff_ignore_missing_internal_colormap;
276
277 static int write_rgb_image(IMAGE *image, TIFF *tif),
278 write_cmapped_image(IMAGE *image, TIFF *tif),
279 write_cmapped24_image(IMAGE *image, TIFF *tif),
280 write_extra(IMAGE *image, TIFF *tif),
281 get_tzup_fields(TIFF *tif, TZUP_FIELDS *tzup_f),
282 get_bits_per_sample(TIFF *tif, USHORT *bps),
283 get_samples_per_pixel(TIFF *tif, USHORT *spp),
284 get_image_sizes(TIFF *tif, int *xsize, int *ysize),
285 get_photometric(TIFF *tif, USHORT *pm),
286 get_resolutions(TIFF *tif, double *x_dpi, double *y_dpi),
287 get_history(TIFF *tif, char **history),
288 get_compression(TIFF *tif, int *compression),
289 get_rows_per_strip(TIFF *tif, long *rowperstrip),
290 get_tag_software(TIFF *tif, char *tag_software),
291 get_orientation(TIFF *tif, int *orientation);
292
293 static bool scanline_needs_swapping(TIFF *tfp);
294
295 static void get_planarconfig(TIFF *tif, USHORT *planargonfig);
296
297 static void get_image_offsets_and_dimensions(TIFF *tif, int xSBsize,
298 int ySBsize, int *x0, int *y0,
299 int *xsize, int *ysize,
300 double *h_pos, UCHAR *extra_mask,
301 TBOOL *edu_file),
302
303 get_plt_name(char *filename, char *pltname),
304
305 clear_image_buffer_16(IMAGE *img, USHORT bg_val),
306 clear_image_buffer_24(IMAGE *img, ULONG bg_val),
307 clear_extra(IMAGE *img, UCHAR bg_val),
308 clear_image_region_buffer_16(USHORT *buffer, int x0, int y0,
309 int clear_xsize, int clear_ysize, int wrap_x,
310 USHORT bg_val),
311 clear_image_region_buffer_24(ULONG *buffer, int x0, int y0, int clear_xsize,
312 int clear_ysize, int wrap_x, ULONG bg_val),
313 clear_extra_region(UCHAR *extra, int x0, int y0, int clear_xsize,
314 int clear_ysize, int wrap_x, UCHAR bg_val);
315
316 static int get_image(TIFF *tif, IMAGE *image),
317 get_image_contig_16(TIFF *tif, IMAGE *image),
318 get_image_contig_24(TIFF *tif, IMAGE *image),
319 get_icon(TIFF *tif, IMAGE *image), get_extra(TIFF *tif, IMAGE *image);
320
321 static char Verbose = 0; /* Variabile per debug */
322
323 /*---------------------------------------------------------------------------*/
324
get_output_compression(void)325 static UINT get_output_compression(void) {
326 static UINT output_compression = 0;
327 /*
328 char *s;
329 if ( !output_compression)
330 {
331 if (tenv_get_var_s("TOONZ_TZUP_COMPRESSION", &s))
332 {
333 if (strstr (s, "rle") || strstr (s, "RLE"))
334 output_compression = COMPRESSION_TOONZ1;
335 else
336 output_compression = COMPRESSION_LZW;
337 }
338 else
339 output_compression = COMPRESSION_LZW;
340 }
341 */
342 return output_compression;
343 }
344
345 /*---------------------------------------------------------------------------*/
346
347 #ifdef CICCIO
img_write_tzup(unsigned short * filename,IMAGE * image)348 int img_write_tzup(unsigned short *filename, IMAGE *image) {
349 TIFF *tfp;
350 int bits_per_sample, samples_per_pixel, photometric, planar_config;
351 int orientation, rows_per_strip, bytes_per_line;
352 int width, height, row, scanline, cmap_size, i;
353 char str[200], *history;
354 UCHAR *outbuf;
355 USHORT window[TOONZWINDOW_COUNT];
356 USHORT palette[TOONZPALETTE_COUNT];
357 TCM_INFO *tcm;
358 UINT tif_compression;
359
360 /* CHECK_IMAGEDLL_LICENSE_AND_GET_IMG_LICENSE_ATTR */
361
362 Silent_tiff_print_error = 1;
363 Tiff_ignore_missing_internal_colormap = 1;
364 tfp = TIFFOpen(filename, "w");
365 if (!tfp) {
366 /*throw "unable to open file for output"; , filename);*/
367 return FALSE;
368 }
369
370 switch (image->type) {
371 CASE RGB : bits_per_sample = 8;
372 samples_per_pixel = 4;
373 photometric = PHOTOMETRIC_RGB;
374 planar_config = PLANARCONFIG_CONTIG;
375 CASE CMAPPED : bits_per_sample = 16;
376 samples_per_pixel = 1;
377 photometric = PHOTOMETRIC_PALETTE;
378 planar_config = PLANARCONFIG_CONTIG;
379 CASE CMAPPED24 : bits_per_sample = 32;
380 samples_per_pixel = 1;
381 photometric = PHOTOMETRIC_PALETTE;
382 planar_config = PLANARCONFIG_CONTIG;
383 DEFAULT:
384 /*tmsg_error("bad image type writing file %s", filename);*/
385 goto bad;
386 }
387
388 orientation = ORIENTATION_BOTLEFT;
389 /*
390 width = image->pixmap.xsize;
391 height = image->pixmap.ysize;
392 */
393 width = image->pixmap.xSBsize;
394 height = image->pixmap.ySBsize;
395
396 if (image->cmap.info.n_pencils && image->cmap.info.n_colors)
397 tcm = &image->cmap.info;
398 else if (image->type == CMAPPED24)
399 tcm = (TCM_INFO *)&Tcm_24_default_info;
400 else
401 tcm = (TCM_INFO *)&Tcm_new_default_info;
402
403 if (image->cmap.offset)
404 cmap_size = TCM_MIN_CMAP_BUFFER_SIZE(*tcm);
405 else
406 cmap_size = TCM_CMAP_BUFFER_SIZE(*tcm);
407 palette[0] = (image->cmap.offset > 0) ? 4 : 3;
408 palette[1] = image->cmap.offset;
409 palette[2] = cmap_size <= 0xffff ? cmap_size : 0;
410 palette[3] = 0 /* tcm->tone_offs */;
411 palette[4] = tcm->tone_bits;
412 palette[5] = tcm->color_offs;
413 palette[6] = tcm->color_bits;
414 palette[7] = tcm->pencil_offs;
415 palette[8] = tcm->pencil_bits;
416 palette[9] = tcm->offset_mask;
417 palette[10] = tcm->n_colors;
418 palette[11] = tcm->n_pencils;
419
420 for (i = 12; i < TOONZPALETTE_COUNT; i++) palette[i] = 0;
421
422 tif_compression = get_output_compression();
423
424 TIFFSetField(tfp, TIFFTAG_TOONZPALETTE, palette);
425 TIFFSetField(tfp, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
426 TIFFSetField(tfp, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel);
427 TIFFSetField(tfp, TIFFTAG_IMAGEWIDTH, width);
428 TIFFSetField(tfp, TIFFTAG_IMAGELENGTH, height);
429 TIFFSetField(tfp, TIFFTAG_ORIENTATION, orientation);
430 TIFFSetField(tfp, TIFFTAG_PLANARCONFIG, planar_config);
431 TIFFSetField(tfp, TIFFTAG_PHOTOMETRIC, photometric);
432 TIFFSetField(tfp, TIFFTAG_COMPRESSION, tif_compression);
433
434 /*
435 * NOTARE CHE VA COMPLETATA LA PARTE RELAITVA AL SETTAGGIO DELLA RISOLUZIONE
436 *
437 */
438 TIFFSetField(tfp, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
439 TIFFSetField(tfp, TIFFTAG_XRESOLUTION, image->pixmap.x_dpi);
440 TIFFSetField(tfp, TIFFTAG_YRESOLUTION, image->pixmap.y_dpi);
441 switch (orientation) {
442 CASE ORIENTATION_BOTLEFT
443 : __OR ORIENTATION_BOTRIGHT
444 : __OR ORIENTATION_TOPLEFT
445 : __OR ORIENTATION_TOPRIGHT
446 : if (image->pixmap.x_dpi) TIFFSetField(
447 tfp, TIFFTAG_XPOSITION,
448 image->pixmap.h_pos / image->pixmap.x_dpi + 8.0);
449 CASE ORIENTATION_LEFTBOT
450 : __OR ORIENTATION_RIGHTBOT
451 : __OR ORIENTATION_LEFTTOP
452 : __OR ORIENTATION_RIGHTTOP
453 : if (image->pixmap.y_dpi) TIFFSetField(
454 tfp, TIFFTAG_XPOSITION,
455 image->pixmap.h_pos / image->pixmap.y_dpi + 8.0);
456 }
457 /*snprintf(str, sizeof(str), "TOONZ %s", versione_del_software);*/
458 TIFFSetField(tfp, TIFFTAG_SOFTWARE, str);
459
460 /* Aggiungo le informazioni relative alla savebox a all'history */
461
462 window[0] = image->pixmap.xD;
463 window[1] = image->pixmap.yD;
464 window[2] = image->pixmap.xsize;
465 window[3] = image->pixmap.ysize;
466 window[4] = image->pixmap.extra_mask;
467
468 for (i = 5; i < TOONZWINDOW_COUNT - 1; i++) window[i] = 0;
469
470 window[TOONZWINDOW_COUNT - 1] = 0;
471 /* (Img_license_attr & TA_TOONZ_EDU) != 0;*/
472
473 TIFFSetField(tfp, TIFFTAG_TOONZWINDOW, window);
474
475 history = build_history();
476 /*
477 if (image->history)
478 {
479 switch(check_history(image->history, history))
480 {
481 CASE APPEND:
482 image->history = append_history(image->history, history);
483 CASE REPLACE:
484 image->history = replace_last_history(image->history, history);
485 DEFAULT:
486 tmsg_error("Internal error: bad history type");
487 abort();
488 }
489 free (history);
490 }
491 else
492 */
493 image->history = history;
494
495 TIFFSetField(tfp, TIFFTAG_TOONZHISTORY, image->history);
496
497 bytes_per_line = TIFFScanlineSize(tfp);
498
499 /*
500 * massima lunghezza di bytes in una strip e' 8k
501 * vedi Graphics File Formats pag.48
502 */
503 if (planar_config == PLANARCONFIG_CONTIG)
504 rows_per_strip = (8 * 1024) / bytes_per_line;
505 else
506 rows_per_strip = 1L;
507
508 TIFFSetField(tfp, TIFFTAG_ROWSPERSTRIP,
509 rows_per_strip == 0 ? 1L : rows_per_strip);
510
511 switch (image->type) {
512 CASE RGB : if (!write_rgb_image(image, tfp)) {
513 // tmsg_error("unable to write buffer to file %s", filename);
514 goto bad;
515 }
516 CASE CMAPPED : if (!write_cmapped_image(image, tfp)) {
517 // tmsg_error("unable to write buffer to file %s", filename);
518 goto bad;
519 }
520 CASE CMAPPED24 : if (!write_cmapped24_image(image, tfp)) {
521 // tmsg_error("unable to write buffer to file %s", filename);
522 goto bad;
523 }
524 DEFAULT:
525 // tmsg_error("bad image type writing file %s", filename);
526 goto bad;
527 }
528
529 Silent_tiff_print_error = 0;
530 Tiff_ignore_missing_internal_colormap = 0;
531 TIFFClose(tfp);
532 return TRUE;
533
534 bad:
535 Silent_tiff_print_error = 0;
536 Tiff_ignore_missing_internal_colormap = 0;
537 TIFFClose(tfp);
538 return FALSE;
539 }
540 #endif
541
542 /*---------------------------------------------------------------------------*/
543
write_rgb_image(IMAGE * image,TIFF * tfp)544 static int write_rgb_image(IMAGE *image, TIFF *tfp) {
545 int scanlinesize;
546 UCHAR *outbuf, *buf;
547 int row, lx, ly, x, wrapx, x0, y0;
548 LPIXEL *gl_buf, *tmp;
549
550 lx = image->pixmap.xSBsize;
551 ly = image->pixmap.ySBsize;
552 x0 = image->pixmap.xD;
553 y0 = image->pixmap.yD;
554 wrapx = image->pixmap.xsize;
555
556 tmp = (LPIXEL *)image->pixmap.buffer + y0 * wrapx + x0;
557 scanlinesize = TIFFScanlineSize(tfp);
558 outbuf = new UCHAR[scanlinesize];
559
560 if (!outbuf) return FALSE;
561
562 for (row = 0; row < ly; row++) {
563 buf = outbuf;
564 gl_buf = tmp;
565 for (x = 0; x < lx; x++) {
566 *buf++ = gl_buf->r;
567 *buf++ = gl_buf->g;
568 *buf++ = gl_buf->b;
569 *buf++ = gl_buf->m;
570 gl_buf++;
571 }
572 if (TIFFWriteScanline(tfp, outbuf, row, 0) < 0) goto bad;
573 tmp += wrapx;
574 }
575
576 delete[] outbuf;
577
578 if (image->pixmap.extra_mask) write_extra(image, tfp);
579
580 return TRUE;
581
582 bad:
583 // tmsg_error("write_scan_line failed at row %d", row);
584 delete[] outbuf;
585 return FALSE;
586 }
587
588 /*---------------------------------------------------------------------------*/
589
write_cmapped_image(IMAGE * image,TIFF * tfp)590 static int write_cmapped_image(IMAGE *image, TIFF *tfp) {
591 int scanline, lx, ly, x0, y0, wrapx;
592 int row;
593 UCHAR *outbuf;
594 USHORT *tmp;
595 int tmp_icon;
596 struct s_pixmap ori_icon;
597 UINT tif_compression;
598
599 tif_compression = get_output_compression();
600
601 tmp_icon = FALSE;
602
603 lx = image->pixmap.xSBsize;
604 ly = image->pixmap.ySBsize;
605 x0 = image->pixmap.xD;
606 y0 = image->pixmap.yD;
607 wrapx = image->pixmap.xsize;
608
609 tmp = image->pixmap.buffer + y0 * wrapx + x0;
610 outbuf = 0;
611 for (row = 0; row < ly; row++) {
612 outbuf = (UCHAR *)tmp;
613 if (TIFFWriteScanline(tfp, outbuf, row, 0) < 0) goto bad;
614 tmp += wrapx;
615 }
616 if (image->pixmap.extra_mask && !image->icon.buffer) {
617 ori_icon = image->icon;
618 // make_icon (image, ICON_WIDTH, ICON_HEIGHT);
619 tmp_icon = TRUE;
620 }
621 if (image->icon.buffer) {
622 if (!TIFFFlush(tfp)) {
623 // tmsg_error("Unable to flush data to .tz(up) file");
624 goto bad;
625 }
626 lx = image->icon.xsize;
627 ly = image->icon.ysize;
628
629 TIFFSetField(tfp, TIFFTAG_SUBFILETYPE, 1);
630 TIFFSetField(tfp, TIFFTAG_BITSPERSAMPLE, 16);
631 TIFFSetField(tfp, TIFFTAG_SAMPLESPERPIXEL, 1);
632 TIFFSetField(tfp, TIFFTAG_IMAGEWIDTH, lx);
633 TIFFSetField(tfp, TIFFTAG_IMAGELENGTH, ly);
634 TIFFSetField(tfp, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
635 TIFFSetField(tfp, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
636 TIFFSetField(tfp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
637 TIFFSetField(tfp, TIFFTAG_COMPRESSION, tif_compression);
638
639 scanline = TIFFScanlineSize(tfp);
640 outbuf = (UCHAR *)image->icon.buffer;
641 for (row = 0; row < ly; row++) {
642 if (TIFFWriteScanline(tfp, outbuf, row, 0) < 0) {
643 // tmsg_error("error writing icon to .tz(up) file");
644 goto bad;
645 }
646 outbuf += scanline;
647 }
648 }
649 if (image->pixmap.extra_mask) write_extra(image, tfp);
650
651 if (tmp_icon && image->icon.buffer) {
652 TFREE(image->icon.buffer)
653 image->icon = ori_icon;
654 }
655 return TRUE;
656
657 bad:
658 if (tmp_icon && image->icon.buffer) {
659 TFREE(image->icon.buffer)
660 image->icon = ori_icon;
661 }
662 return FALSE;
663 }
664
665 /*---------------------------------------------------------------------------*/
666
write_cmapped24_image(IMAGE * image,TIFF * tfp)667 static int write_cmapped24_image(IMAGE *image, TIFF *tfp) {
668 int scanline, lx, ly, x0, y0, wrapx;
669 int row;
670 UCHAR *outbuf;
671 ULONG *tmp;
672 UINT tif_compression;
673
674 tif_compression = get_output_compression();
675
676 lx = image->pixmap.xSBsize;
677 ly = image->pixmap.ySBsize;
678 x0 = image->pixmap.xD;
679 y0 = image->pixmap.yD;
680 wrapx = image->pixmap.xsize;
681
682 tmp = (ULONG *)image->pixmap.buffer + y0 * wrapx + x0;
683 outbuf = 0;
684 for (row = 0; row < ly; row++) {
685 outbuf = (UCHAR *)tmp;
686 if (TIFFWriteScanline(tfp, outbuf, row, 0) < 0) goto bad;
687 tmp += wrapx;
688 }
689
690 if (image->icon.buffer) {
691 if (!TIFFFlush(tfp)) {
692 // tmsg_error("Unable to flush data to .tz(up) file");
693 goto bad;
694 }
695 lx = image->icon.xsize;
696 ly = image->icon.ysize;
697
698 TIFFSetField(tfp, TIFFTAG_SUBFILETYPE, 1);
699 TIFFSetField(tfp, TIFFTAG_BITSPERSAMPLE, 32);
700 TIFFSetField(tfp, TIFFTAG_SAMPLESPERPIXEL, 1);
701 TIFFSetField(tfp, TIFFTAG_IMAGEWIDTH, lx);
702 TIFFSetField(tfp, TIFFTAG_IMAGELENGTH, ly);
703 TIFFSetField(tfp, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
704 TIFFSetField(tfp, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
705 TIFFSetField(tfp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
706 TIFFSetField(tfp, TIFFTAG_COMPRESSION, tif_compression);
707
708 scanline = TIFFScanlineSize(tfp);
709 outbuf = (UCHAR *)image->icon.buffer;
710 for (row = 0; row < ly; row++) {
711 if (TIFFWriteScanline(tfp, outbuf, row, 0) < 0) {
712 // tmsg_error("error writing icon to .tz(up) file");
713 goto bad;
714 }
715 outbuf += scanline;
716 }
717 }
718 return TRUE;
719
720 bad:
721 return FALSE;
722 }
723
724 /*---------------------------------------------------------------------------*/
725
write_extra(IMAGE * image,TIFF * tfp)726 static int write_extra(IMAGE *image, TIFF *tfp) {
727 int lx, ly, x0, y0, wrapx, row;
728 UCHAR *extra;
729 UINT tif_compression;
730 int rowsperstrip;
731
732 if (!image->pixmap.extra_mask) return TRUE;
733
734 tif_compression = get_output_compression();
735
736 if (!TIFFFlush(tfp)) {
737 // tmsg_error("Unable to flush data to .tz(up) file");
738 goto bad;
739 }
740 lx = image->pixmap.xSBsize;
741 ly = image->pixmap.ySBsize;
742 x0 = image->pixmap.xD;
743 y0 = image->pixmap.yD;
744 wrapx = image->pixmap.xsize;
745
746 TIFFSetField(tfp, TIFFTAG_SUBFILETYPE, 1);
747 TIFFSetField(tfp, TIFFTAG_BITSPERSAMPLE, 8);
748 TIFFSetField(tfp, TIFFTAG_SAMPLESPERPIXEL, 1);
749 TIFFSetField(tfp, TIFFTAG_IMAGEWIDTH, lx);
750 TIFFSetField(tfp, TIFFTAG_IMAGELENGTH, ly);
751 TIFFSetField(tfp, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
752 TIFFSetField(tfp, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
753 TIFFSetField(tfp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
754 TIFFSetField(tfp, TIFFTAG_COMPRESSION, tif_compression);
755
756 rowsperstrip = (8 * 1024) / lx; /* contig, 1 byte per pixel */
757 NOT_LESS_THAN(1, rowsperstrip)
758 TIFFSetField(tfp, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
759
760 extra = image->pixmap.extra + y0 * wrapx + x0;
761 for (row = 0; row < ly; row++) {
762 if (TIFFWriteScanline(tfp, extra, row, 0) < 0) goto bad;
763 extra += wrapx;
764 }
765 return TRUE;
766
767 bad:
768 // tmsg_error ("error writing extra information to .tz(up) file");
769 return FALSE;
770 }
771
772 /*===========================================================================*/
773
next_img_read_with_extra(void)774 void next_img_read_with_extra(void) { Next_img_read_with_extra = TRUE; }
775
776 /*===========================================================================*/
777
load()778 TImageP TImageReaderTZP::load() {
779 /*
780 FILE *fp;
781 if ((fp = _wfopen(getFilePath().getWideString().c_str(), L"rb")) == NULL)
782 {
783 throw TImageException(getFilePath(),"can't open file");
784 }
785
786 //{
787 // fclose(fp);
788 // throw TImageException(getFilePath(),"invalid file format");
789 //}
790
791 TRaster32P raster(lx,ly);
792 TPixel32* row;
793
794 TRasterImageP rasImage(raster);
795
796 TImageP image(rasImage);
797
798 */
799
800 wstring fn = getFilePath().getWideString();
801 TIFF *tfp;
802 IMAGE *image = NIL;
803 TZUP_FIELDS tzup_f;
804 // char pltname[1024];
805 USHORT *window = NIL;
806 USHORT *palette; /* [TOONZPALETTE_COUNT] */
807 // int max_n_colors, max_n_pencils;
808
809 /*
810 CHECK_IMAGEDLL_LICENSE_AND_GET_IMG_LICENSE_ATTR
811 SET_READ_WITH_EXTRA
812 */
813
814 Silent_tiff_print_error = 1;
815 Tiff_ignore_missing_internal_colormap = 1;
816 tfp = TIFFOpen(fn.c_str(), "r");
817 if (!tfp) return TImageP();
818
819 if (!get_tzup_fields(tfp, &tzup_f)) return TImageP();
820
821 /*
822 if (tzup_f.edu_file && !(Img_license_attr & TA_TOONZ_EDU))
823 {
824 char str[1024];
825 BUILD_EDU_ERROR_STRING(str)
826 tmsg_error (str);
827 goto bad;
828 }
829 */
830
831 // image = new IMAGE; // new_img();
832 // if (!image)
833 // goto bad;
834
835 if (!TIFFGetField(tfp, TIFFTAG_TOONZPALETTE, &palette)) {
836 // image->cmap.info = Tcm_old_default_info;
837 } else {
838 //// image->cmap.info.tone_offs = palette[3]; sempre 0
839 /*
840 image->cmap.info.tone_bits = (UCHAR)palette[4];
841 image->cmap.info.color_offs = (UCHAR)palette[5];
842 image->cmap.info.color_bits = (UCHAR)palette[6];
843 image->cmap.info.pencil_offs = (UCHAR)palette[7];
844 image->cmap.info.pencil_bits = (UCHAR)palette[8];
845 image->cmap.info.offset_mask = palette[9];
846 image->cmap.info.n_tones = 1 << palette[4];
847 image->cmap.info.n_colors = palette[10];
848 image->cmap.info.n_pencils = palette[11];
849 image->cmap.info.default_val = (image->cmap.info.n_tones-1) |
850 image->cmap.info.offset_mask;
851 */
852 }
853
854 /* estendo la palette */
855
856 /*
857 max_n_colors = 1 << image->cmap.info.color_bits;
858 max_n_pencils = 1 << image->cmap.info.pencil_bits;
859 if (max_n_colors > image->cmap.info.n_colors ||
860 max_n_pencils > image->cmap.info.n_pencils)
861 {
862 image->cmap.info.n_colors = max_n_colors;
863 image->cmap.info.n_pencils = max_n_pencils;
864 image->cmap.color_n = image->cmap.info.n_colors;
865 image->cmap.pencil_n = image->cmap.info.n_pencils;
866 }
867 */
868
869 TRasterCM16P raster(tzup_f.xsize, tzup_f.ysize);
870
871 ///===========
872 {
873 bool swapNeeded = scanline_needs_swapping(tfp);
874
875 int x0 = tzup_f.x0;
876 int y0 = tzup_f.y0;
877 int lx = tzup_f.xSBsize;
878 int ly = tzup_f.ySBsize;
879 int x1 = x0 + lx - 1;
880 int y1 = y0 + ly - 1;
881 int xsize = tzup_f.xsize;
882 int ysize = tzup_f.ysize;
883
884 int wrap = tzup_f.xsize;
885
886 assert(raster->getBounds().contains(TRect(x0, y0, x1, y1)));
887 raster->fillOutside(TRect(x0, y0, x1, y1), TPixelCM16(0, 0, 15));
888 raster->lock();
889 for (int y = y0; y <= y1; y++) {
890 TPixelCM16 *row = raster->pixels(y) + x0;
891 if (TIFFReadScanline(tfp, (UCHAR *)row, y - y0, 0) < 0)
892 if (swapNeeded) TIFFSwabArrayOfShort((USHORT *)row, lx);
893 }
894 raster->unlock();
895 /*
896 buf = image->pixmap.buffer;
897 default_val = image->cmap.info.default_val;
898 for (y = 0; y < y0; y++)
899 {
900 pix = buf + y * wrap;
901 for (x = 0; x < xsize; x++)
902 *pix++ = default_val;
903 }
904 for ( ; y <= y1; y++)
905 {
906 pix = buf + y * wrap;
907 for (x = 0; x < x0; x++)
908 *pix++ = default_val;
909 if (TIFFReadScanline (tf, (UCHAR *)pix, y - y0, 0) < 0)
910 {
911 static int gia_dato = FALSE;
912 if ( !gia_dato)
913 {
914 //tmsg_error("bad data read on line %d", y);
915 gia_dato = TRUE;
916 }
917 memset (pix, 0, lx * sizeof(*pix));
918 }
919 if (swap_needed)
920 TIFFSwabArrayOfShort((USHORT *)pix, lx);
921 pix += lx;
922 for (x = x1 + 1; x < xsize; x++)
923 *pix++ = default_val;
924 }
925 for ( ; y < ysize; y++)
926 {
927 pix = buf + y * wrap;
928 for (x = 0; x < xsize; x++)
929 *pix++ = default_val;
930 }
931 */
932 }
933 ///===========
934
935 switch (tzup_f.photometric) {
936 CASE PHOTOMETRIC_MINISBLACK : __OR PHOTOMETRIC_MINISWHITE
937 : __OR PHOTOMETRIC_RGB
938 :; // image->type = RGB;
939
940 CASE PHOTOMETRIC_PALETTE :
941 /*
942 if (tzup_f.bits_per_sample == 32)
943 image->type = CMAPPED24;
944 else
945 image->type = CMAPPED;
946 */
947
948 DEFAULT:
949 // tmsg_error("bad photometric interpretation in file %s", filename);
950 // goto bad;
951 ;
952 }
953
954 // if (!get_history(tfp, &image->history))
955 // image->history = NIL;
956
957 // image->pixmap.extra_mask = tzup_f.extra_mask;
958
959 // if (!allocate_pixmap(image, tzup_f.xsize, tzup_f.ysize))
960 // image->pixmap.buffer = new USHORT[tzup_f.xsize*tzup_f.ysize];
961 // if(!image->pixmap.buffer)
962 // goto bad;
963
964 // image->pixmap.xD = tzup_f.x0;
965 // image->pixmap.yD = tzup_f.y0;
966 // image->pixmap.xSBsize = tzup_f.xSBsize;
967 // image->pixmap.ySBsize = tzup_f.ySBsize;
968
969 /*
970 if (!get_image(tfp, image))
971 {
972 //tmsg_error("no image while reading file %s", filename);
973 goto bad;
974 }
975 if (!get_icon(tfp, image))
976 {
977 //make_icon(image, ICON_WIDTH, ICON_HEIGHT);
978 }
979 if (image->pixmap.extra)
980 if ( !get_extra (tfp, image))
981 {
982 //tmsg_error("missing extra information while reading file %s", filename);
983 goto bad;
984 }
985 image->pixmap.x_dpi = tzup_f.x_dpi;
986 image->pixmap.y_dpi = tzup_f.y_dpi;
987 image->pixmap.h_pos = tzup_f.h_pos;
988
989 Silent_tiff_print_error = 0;
990 Tiff_ignore_missing_internal_colormap = 0;
991 */
992
993 TIFFClose(tfp);
994
995 // image->filename = 0; // strsave(filename);
996
997 // get_plt_name(filename, pltname);
998 // image->cmap.name = 0; // strsave(pltname);
999
1000 assert(0);
1001 return 0;
1002 // TToonzImageP toonzImage(raster);
1003 // return TImageP(toonzImage);
1004
1005 /*
1006 bad:
1007 if (image)
1008 {
1009 //free_img(image);
1010 }
1011 Silent_tiff_print_error = 0;
1012 Tiff_ignore_missing_internal_colormap = 0;
1013 if (tfp)
1014 TIFFClose(tfp);
1015 return NIL;
1016
1017 */
1018 }
1019
1020 /*===========================================================================*/
1021
scanline_needs_swapping(TIFF * tfp)1022 static bool scanline_needs_swapping(TIFF *tfp) {
1023 USHORT compression;
1024
1025 TIFFGetField(tfp, TIFFTAG_COMPRESSION, &compression);
1026 return compression == COMPRESSION_LZW && TIFFNeedSwab(tfp);
1027 }
1028
1029 /*---------------------------------------------------------------------------*/
1030
read_region_tzup_16(IMAGE * image,TIFF * tfp,char * filename,INFO_REGION * region,int scale,UCHAR * buf,int scanline_size,int rowperstrip,int wrap_out,int xD_offset,int yD_offset)1031 static int read_region_tzup_16(IMAGE *image, TIFF *tfp, char *filename,
1032 INFO_REGION *region, int scale, UCHAR *buf,
1033 int scanline_size, int rowperstrip, int wrap_out,
1034 int xD_offset, int yD_offset) {
1035 USHORT *inp = NIL, *outp = NIL, *appo_outp = NIL;
1036 int row, nrow, rrow;
1037 TBOOL swap_needed;
1038
1039 swap_needed = scanline_needs_swapping(tfp);
1040
1041 appo_outp = image->pixmap.buffer + yD_offset * wrap_out + xD_offset;
1042
1043 if (Verbose) printf("Posizione in uscita: %d, %d\n", xD_offset, yD_offset);
1044
1045 /* Puntatore per avanzamento nel buffer della regione */
1046 outp = appo_outp;
1047
1048 row = region->startScanRow;
1049 /*
1050 * Questa serie di scanline viene fatta perche' non viene
1051 * accettato un accesso random alle righe del file.
1052 */
1053 if (row > 0) {
1054 int c;
1055 c = (row / rowperstrip) * rowperstrip;
1056 for (; c < row; c++) {
1057 if (TIFFReadScanline(tfp, buf, c, 0) < 0) {
1058 // tmsg_error("bad image data read on line %d of file %s", c, filename);
1059 return FALSE;
1060 }
1061 }
1062 }
1063 for (nrow = 0; nrow < region->scanNrow; nrow++) {
1064 appo_outp = outp;
1065 if (TIFFReadScanline(tfp, buf, row, 0) < 0) {
1066 // tmsg_error("bad image data read at line %d of file %s", row, filename);
1067 return FALSE;
1068 }
1069 if (swap_needed)
1070 TIFFSwabArrayOfShort((USHORT *)buf, scanline_size / sizeof(USHORT));
1071
1072 inp = (USHORT *)buf + region->startScanCol;
1073 for (rrow = 0; rrow < region->scanNcol; rrow++) {
1074 *outp++ = *inp;
1075 inp += scale;
1076 }
1077 if (scale > 1) {
1078 register currRow = 0, stepRow = 1, nextRow = 0;
1079 if (row + scale > region->ly_in)
1080 break;
1081 else
1082 nextRow = row + scale;
1083 stepRow = (nextRow / rowperstrip) * rowperstrip;
1084 for (currRow = stepRow; currRow < nextRow; currRow++) {
1085 if (TIFFReadScanline(tfp, buf, currRow, 0) < 0) {
1086 // tmsg_error("bad image data in file %s at line %d", filename,
1087 // currRow);
1088 return FALSE;
1089 }
1090 }
1091 }
1092 outp = appo_outp + wrap_out;
1093 row += scale;
1094 }
1095 return TRUE;
1096 }
1097
1098 /*---------------------------------------------------------------------------*/
1099
read_region_tzup_24(IMAGE * image,TIFF * tfp,char * filename,INFO_REGION * region,int scale,UCHAR * buf,int scanline_size,int rowperstrip,int wrap_out,int xD_offset,int yD_offset)1100 static int read_region_tzup_24(IMAGE *image, TIFF *tfp, char *filename,
1101 INFO_REGION *region, int scale, UCHAR *buf,
1102 int scanline_size, int rowperstrip, int wrap_out,
1103 int xD_offset, int yD_offset) {
1104 ULONG *inp = NIL, *outp = NIL, *appo_outp = NIL;
1105 int row, nrow, rrow;
1106 TBOOL swap_needed;
1107
1108 swap_needed = scanline_needs_swapping(tfp);
1109
1110 appo_outp = (ULONG *)image->pixmap.buffer + yD_offset * wrap_out + xD_offset;
1111
1112 if (Verbose) printf("Posizione in uscita: %d, %d\n", xD_offset, yD_offset);
1113
1114 /* Puntatore per avanzamento nel buffer della regione */
1115 outp = appo_outp;
1116
1117 row = region->startScanRow;
1118 /*
1119 * Questa serie di scanline viene fatta perche' non viene
1120 * accettato un accesso random alle righe del file.
1121 */
1122 if (row > 0) {
1123 int c;
1124 c = (row / rowperstrip) * rowperstrip;
1125 for (; c < row; c++) {
1126 if (TIFFReadScanline(tfp, buf, c, 0) < 0) {
1127 // tmsg_error("bad image data read on line %d of file %s", c, filename);
1128 return FALSE;
1129 }
1130 }
1131 }
1132 for (nrow = 0; nrow < region->scanNrow; nrow++) {
1133 appo_outp = outp;
1134 if (TIFFReadScanline(tfp, buf, row, 0) < 0) {
1135 // tmsg_error("bad image data read at line %d of file %s", row, filename);
1136 return FALSE;
1137 }
1138 if (swap_needed)
1139 TIFFSwabArrayOfLong((TUINT32 *)buf, scanline_size / sizeof(ULONG));
1140
1141 inp = (ULONG *)buf + region->startScanCol;
1142 for (rrow = 0; rrow < region->scanNcol; rrow++) {
1143 *outp++ = *inp;
1144 inp += scale;
1145 }
1146 if (scale > 1) {
1147 register currRow = 0, stepRow = 1, nextRow = 0;
1148 if (row + scale > region->ly_in)
1149 break;
1150 else
1151 nextRow = row + scale;
1152 stepRow = (nextRow / rowperstrip) * rowperstrip;
1153 for (currRow = stepRow; currRow < nextRow; currRow++) {
1154 if (TIFFReadScanline(tfp, buf, currRow, 0) < 0) {
1155 // tmsg_error("bad image data in file %s at line %d", filename,
1156 // currRow);
1157 return FALSE;
1158 }
1159 }
1160 }
1161 outp = appo_outp + wrap_out;
1162 row += scale;
1163 }
1164 return TRUE;
1165 }
1166
1167 /*===========================================================================*/
1168
read_region_extra(IMAGE * image,TIFF * tfp,char * filename,INFO_REGION * region,int scale,UCHAR * buf,int wrap_out,int xD_offset,int yD_offset)1169 static int read_region_extra(IMAGE *image, TIFF *tfp, char *filename,
1170 INFO_REGION *region, int scale, UCHAR *buf,
1171 int wrap_out, int xD_offset, int yD_offset) {
1172 UCHAR *inp = NIL, *outp = NIL, *appo_outp = NIL;
1173 int row, nrow, rrow;
1174 int scanline_size, rowperstrip;
1175
1176 if (!TIFFReadDirectory(tfp)) return FALSE;
1177
1178 scanline_size = TIFFScanlineSize(tfp);
1179 if (!TIFFGetField(tfp, TIFFTAG_ROWSPERSTRIP, &rowperstrip))
1180 rowperstrip = MAXINT / 2;
1181
1182 appo_outp = image->pixmap.extra + yD_offset * wrap_out + xD_offset;
1183
1184 if (Verbose)
1185 printf("Posizione in uscita (extra): %d, %d\n", xD_offset, yD_offset);
1186
1187 /* Puntatore per avanzamento nel buffer della regione */
1188 outp = appo_outp;
1189
1190 row = region->startScanRow;
1191 /*
1192 * Questa serie di scanline viene fatta perche' non viene
1193 * accettato un accesso random alle righe del file.
1194 */
1195 if (row > 0) {
1196 int c;
1197 c = (row / rowperstrip) * rowperstrip;
1198 for (; c < row; c++) {
1199 if (TIFFReadScanline(tfp, buf, c, 0) < 0) {
1200 // tmsg_error("bad extra data read on line %d of file %s", c, filename);
1201 return FALSE;
1202 }
1203 }
1204 }
1205 for (nrow = 0; nrow < region->scanNrow; nrow++) {
1206 appo_outp = outp;
1207 if (TIFFReadScanline(tfp, buf, row, 0) < 0) {
1208 // tmsg_error("bad extra data read at line %d of file %s", row, filename);
1209 return FALSE;
1210 }
1211
1212 inp = buf + region->startScanCol;
1213 for (rrow = 0; rrow < region->scanNcol; rrow++) {
1214 *outp++ = *inp;
1215 inp += scale;
1216 }
1217 if (scale > 1) {
1218 register currRow = 0, stepRow = 1, nextRow = 0;
1219 if (row + scale > region->ly_in)
1220 break;
1221 else
1222 nextRow = row + scale;
1223 stepRow = (nextRow / rowperstrip) * rowperstrip;
1224 for (currRow = stepRow; currRow < nextRow; currRow++) {
1225 if (TIFFReadScanline(tfp, buf, currRow, 0) < 0) {
1226 // tmsg_error("bad extra data in file %s at line %d", filename,
1227 // currRow);
1228 return FALSE;
1229 }
1230 }
1231 }
1232 outp = appo_outp + wrap_out;
1233 row += scale;
1234 }
1235 return TRUE;
1236 }
1237
1238 /*---------------------------------------------------------------------------*/
1239 #ifdef CICCIO
img_read_region_tzup(unsigned short * filename,int x1,int y1,int x2,int y2,int scale)1240 IMAGE *img_read_region_tzup(unsigned short *filename, int x1, int y1, int x2,
1241 int y2, int scale) {
1242 TIFF *tfp = NIL;
1243 IMAGE *image = NIL;
1244 INFO_REGION region;
1245 TZUP_FIELDS tzup_f;
1246 char pltname[1024];
1247 UCHAR *buf = NIL;
1248 USHORT planarconfig;
1249 int rowperstrip;
1250 int xsize_out, ysize_out, clear_xsize, clear_ysize;
1251 int xD_offset, yD_offset;
1252 int x1_reg, y1_reg, x2_reg, y2_reg;
1253 int box_x1, box_y1, box_x2, box_y2;
1254 USHORT *palette; /* [TOONZPALETTE_COUNT] */
1255 int scanline_size;
1256 int ret;
1257 int max_n_colors, max_n_pencils;
1258
1259 /*
1260 CHECK_IMAGEDLL_LICENSE_AND_GET_IMG_LICENSE_ATTR
1261 SET_READ_WITH_EXTRA
1262 */
1263
1264 Silent_tiff_print_error = 1;
1265 Tiff_ignore_missing_internal_colormap = 1;
1266 tfp = TIFFOpen(filename, "r");
1267 if (!tfp) return NIL;
1268
1269 if (!get_tzup_fields(tfp, &tzup_f)) goto bad;
1270
1271 /*
1272 if (tzup_f.edu_file && !(Img_license_attr & TA_TOONZ_EDU))
1273 {
1274 char str[1024];
1275 BUILD_EDU_ERROR_STRING(str)
1276 tmsg_error (str);
1277 goto bad;
1278 }
1279 */
1280
1281 TIFFGetField(tfp, TIFFTAG_ROWSPERSTRIP, &rowperstrip);
1282
1283 TIFFGetField(tfp, TIFFTAG_PLANARCONFIG, &planarconfig);
1284 if (planarconfig == PLANARCONFIG_SEPARATE) {
1285 // tmsg_error("separate buffer image in file %s not supported
1286 // yet",filename);
1287 goto bad;
1288 }
1289
1290 image = new IMAGE; // new_img();
1291 if (!image) goto bad;
1292
1293 if (!TIFFGetField(tfp, TIFFTAG_TOONZPALETTE, &palette)) {
1294 image->cmap.info = Tcm_old_default_info;
1295 } else {
1296 /*image->cmap.info.tone_offs = palette[3]; */
1297 image->cmap.info.tone_bits = (UCHAR)palette[4];
1298 image->cmap.info.color_offs = (UCHAR)palette[5];
1299 image->cmap.info.color_bits = (UCHAR)palette[6];
1300 image->cmap.info.pencil_offs = (UCHAR)palette[7];
1301 image->cmap.info.pencil_bits = (UCHAR)palette[8];
1302 image->cmap.info.offset_mask = palette[9];
1303 image->cmap.info.n_tones = 1 << palette[4];
1304 image->cmap.info.n_colors = palette[10];
1305 image->cmap.info.n_pencils = palette[11];
1306 image->cmap.info.default_val =
1307 (image->cmap.info.n_tones - 1) | image->cmap.info.offset_mask;
1308 }
1309
1310 /* estendo la palette */
1311
1312 max_n_colors = 1 << image->cmap.info.color_bits;
1313 max_n_pencils = 1 << image->cmap.info.pencil_bits;
1314 if (max_n_colors > image->cmap.info.n_colors ||
1315 max_n_pencils > image->cmap.info.n_pencils) {
1316 image->cmap.info.n_colors = max_n_colors;
1317 image->cmap.info.n_pencils = max_n_pencils;
1318 image->cmap.color_n = image->cmap.info.n_colors;
1319 image->cmap.pencil_n = image->cmap.info.n_pencils;
1320 }
1321
1322 switch (tzup_f.photometric) {
1323 CASE PHOTOMETRIC_MINISBLACK : __OR PHOTOMETRIC_MINISWHITE
1324 : __OR PHOTOMETRIC_RGB : image->type = RGB;
1325
1326 CASE PHOTOMETRIC_PALETTE : if (tzup_f.bits_per_sample == 32) image->type =
1327 CMAPPED24;
1328 else image->type = CMAPPED;
1329
1330 DEFAULT:
1331 // tmsg_error("bad photometric interpretation in file %s", filename);
1332 goto bad;
1333 }
1334
1335 x1_reg = x1 - tzup_f.x0;
1336 y1_reg = y1 - tzup_f.y0;
1337
1338 x2_reg = x2 - tzup_f.x0;
1339 y2_reg = y2 - tzup_f.y0;
1340
1341 xsize_out = (x2 - x1) / scale + 1;
1342 ysize_out = (y2 - y1) / scale + 1;
1343
1344 getInfoRegion(®ion, x1_reg, y1_reg, x2_reg, y2_reg, scale, tzup_f.xSBsize,
1345 tzup_f.ySBsize);
1346
1347 xD_offset = region.x_offset;
1348 yD_offset = region.y_offset;
1349
1350 // if (Verbose)
1351 // printInfoRegion(®ion);
1352
1353 image->pixmap.extra_mask = tzup_f.extra_mask;
1354
1355 // if (!allocate_pixmap(image, xsize_out, ysize_out))
1356 image->pixmap.buffer = new USHORT[xsize_out * ysize_out];
1357 if (image->pixmap.buffer) goto bad;
1358
1359 if (TRUE /* x1 != 0 || x2 != tzup_f.xsize - 1 ||
1360 y1 != 0 || y2 != tzup_f.ysize - 1 */) {
1361 clear_xsize = xsize_out;
1362 clear_ysize = ysize_out;
1363 if (image->type == CMAPPED)
1364 clear_image_region_buffer_16(image->pixmap.buffer, 0, 0, clear_xsize,
1365 clear_ysize, xsize_out,
1366 image->cmap.info.offset_mask + 15);
1367 else if (image->type == CMAPPED24)
1368 clear_image_region_buffer_24((ULONG *)image->pixmap.buffer, 0, 0,
1369 clear_xsize, clear_ysize, xsize_out, 255);
1370 else
1371 abort();
1372 } else {
1373 clear_xsize = 0;
1374 clear_ysize = 0;
1375 }
1376 if (Verbose) {
1377 printf("Clear xsize/xsize_out: %d/%d in %d:\n", clear_xsize, xsize_out,
1378 tzup_f.xsize);
1379 printf("Clear ysize/ysize_out: %d/%d in %d:\n", clear_ysize, ysize_out,
1380 tzup_f.ysize);
1381 }
1382 if (image->pixmap.extra)
1383 clear_extra_region(image->pixmap.extra, 0, 0, clear_xsize, clear_ysize,
1384 xsize_out, 0);
1385 box_x1 = tzup_f.x0;
1386 box_y1 = tzup_f.y0;
1387 box_x2 = tzup_f.x0 + tzup_f.xSBsize - 1;
1388 box_y2 = tzup_f.y0 + tzup_f.ySBsize - 1;
1389 if (x1 > box_x2 || x2 < box_x1 || y1 > box_y2 || y2 < box_y1) {
1390 image->pixmap.xsize = xsize_out;
1391 image->pixmap.ysize = ysize_out;
1392 image->pixmap.xSBsize = xsize_out;
1393 image->pixmap.ySBsize = ysize_out;
1394 image->pixmap.xD = 0;
1395 image->pixmap.yD = 0;
1396 image->pixmap.x_dpi = tzup_f.x_dpi;
1397 image->pixmap.y_dpi = tzup_f.y_dpi;
1398 image->pixmap.h_pos = tzup_f.h_pos;
1399 image->filename = strsave(filename);
1400 get_plt_name(filename, pltname);
1401 image->cmap.name = strsave(pltname);
1402 goto ok;
1403 }
1404 image->pixmap.xD = xD_offset;
1405 image->pixmap.yD = yD_offset;
1406 image->pixmap.xSBsize = region.scanNcol;
1407 image->pixmap.ySBsize = region.scanNrow;
1408
1409 /* Buffer per la scanline */
1410 scanline_size = TIFFScanlineSize(tfp);
1411 TMALLOC(buf, scanline_size)
1412 if (!buf) goto bad;
1413
1414 switch (image->type) {
1415 CASE CMAPPED : ret = read_region_tzup_16(
1416 image, tfp, filename, ®ion, scale, buf, scanline_size,
1417 rowperstrip, xsize_out, xD_offset, yD_offset);
1418 CASE CMAPPED24
1419 : ret = read_region_tzup_24(image, tfp, filename, ®ion, scale, buf,
1420 scanline_size, rowperstrip, xsize_out,
1421 xD_offset, yD_offset);
1422 DEFAULT:
1423 ret = FALSE;
1424 abort();
1425 }
1426 if (!ret) goto bad;
1427
1428 image->pixmap.x_dpi = tzup_f.x_dpi;
1429 image->pixmap.y_dpi = tzup_f.y_dpi;
1430 image->pixmap.h_pos = tzup_f.h_pos;
1431
1432 image->filename = strsave(filename);
1433 get_plt_name(filename, pltname);
1434 image->cmap.name = strsave(pltname);
1435
1436 if (!get_icon(tfp, image)) make_icon(image, ICON_WIDTH, ICON_HEIGHT);
1437
1438 if (image->pixmap.extra) {
1439 ret = read_region_extra(image, tfp, filename, ®ion, scale, buf,
1440 xsize_out, xD_offset, yD_offset);
1441 if (!ret) goto bad;
1442 }
1443
1444 ok:
1445 Silent_tiff_print_error = 0;
1446 Tiff_ignore_missing_internal_colormap = 0;
1447 TIFFClose(tfp);
1448 TFREE(buf);
1449 return image;
1450
1451 bad:
1452 if (image) free_img(image);
1453 Silent_tiff_print_error = 0;
1454 Tiff_ignore_missing_internal_colormap = 0;
1455 TIFFClose(tfp);
1456 TFREE(buf);
1457 return NIL;
1458 }
1459
1460 #endif
1461
1462 /*---------------------------------------------------------------------------*/
1463
img_read_tzup_info(unsigned short * filename)1464 IMAGE *img_read_tzup_info(unsigned short *filename) {
1465 TIFF *tfp;
1466 IMAGE *image = NIL;
1467 TZUP_FIELDS tzup_f;
1468 USHORT *palette; /* [TOONZPALETTE_COUNT] */
1469 int max_n_colors, max_n_pencils;
1470
1471 /* CHECK_IMAGEDLL_LICENSE_AND_GET_IMG_LICENSE_ATTR */
1472
1473 Silent_tiff_print_error = 1;
1474 Tiff_ignore_missing_internal_colormap = 1;
1475
1476 tfp = TIFFOpen((wchar_t *)filename, "r");
1477 if (!tfp) goto bad;
1478
1479 if (!get_tzup_fields(tfp, &tzup_f)) goto bad;
1480
1481 /*if (tzup_f.edu_file && !(Img_license_attr & TA_TOONZ_EDU))
1482 {
1483 char str[1024];
1484 BUILD_EDU_ERROR_STRING(str)
1485 tmsg_warning (str);
1486 }
1487 */
1488
1489 image = new IMAGE; // new_img();
1490 if (!image) goto bad;
1491
1492 if (!TIFFGetField(tfp, TIFFTAG_TOONZPALETTE, &palette)) {
1493 image->cmap.info = Tcm_old_default_info;
1494 } else {
1495 /*image->cmap.info.tone_offs = palette[3]; */
1496 image->cmap.info.tone_bits = (UCHAR)palette[4];
1497 image->cmap.info.color_offs = (UCHAR)palette[5];
1498 image->cmap.info.color_bits = (UCHAR)palette[6];
1499 image->cmap.info.pencil_offs = (UCHAR)palette[7];
1500 image->cmap.info.pencil_bits = (UCHAR)palette[8];
1501 image->cmap.info.offset_mask = palette[9];
1502 image->cmap.info.n_tones = 1 << palette[4];
1503 image->cmap.info.n_colors = palette[10];
1504 image->cmap.info.n_pencils = palette[11];
1505 image->cmap.info.default_val =
1506 (image->cmap.info.n_tones - 1) | image->cmap.info.offset_mask;
1507 }
1508
1509 /* estendo la palette */
1510
1511 max_n_colors = 1 << image->cmap.info.color_bits;
1512 max_n_pencils = 1 << image->cmap.info.pencil_bits;
1513 if (max_n_colors > image->cmap.info.n_colors ||
1514 max_n_pencils > image->cmap.info.n_pencils) {
1515 image->cmap.info.n_colors = max_n_colors;
1516 image->cmap.info.n_pencils = max_n_pencils;
1517 image->cmap.color_n = image->cmap.info.n_colors;
1518 image->cmap.pencil_n = image->cmap.info.n_pencils;
1519 }
1520
1521 switch (tzup_f.photometric) {
1522 CASE PHOTOMETRIC_MINISBLACK : __OR PHOTOMETRIC_MINISWHITE
1523 : __OR PHOTOMETRIC_RGB : image->type = RGB;
1524
1525 CASE PHOTOMETRIC_PALETTE : if (tzup_f.bits_per_sample == 32) image->type =
1526 CMAPPED24;
1527 else image->type = CMAPPED;
1528
1529 DEFAULT:
1530 // tmsg_error("bad photometric interpretation in file %s", filename);
1531 goto bad;
1532 }
1533 image->pixmap.extra_mask = tzup_f.extra_mask;
1534
1535 if (!get_history(tfp, &image->history)) {
1536 image->history = NIL;
1537 }
1538 image->pixmap.xsize = tzup_f.xsize;
1539 image->pixmap.ysize = tzup_f.ysize;
1540 image->pixmap.xD = tzup_f.x0;
1541 image->pixmap.yD = tzup_f.y0;
1542 image->pixmap.xSBsize = tzup_f.xSBsize;
1543 image->pixmap.ySBsize = tzup_f.ySBsize;
1544 image->pixmap.x_dpi = tzup_f.x_dpi;
1545 image->pixmap.y_dpi = tzup_f.y_dpi;
1546 image->pixmap.h_pos = tzup_f.h_pos;
1547
1548 Silent_tiff_print_error = 0;
1549 Tiff_ignore_missing_internal_colormap = 0;
1550 TIFFClose(tfp);
1551 return image;
1552
1553 bad:
1554 if (image) {
1555 // free_img(image);
1556 }
1557 Silent_tiff_print_error = 0;
1558 Tiff_ignore_missing_internal_colormap = 0;
1559 if (tfp) TIFFClose(tfp);
1560 return NIL;
1561 }
1562
1563 /*---------------------------------------------------------------------------*/
1564
1565 #ifdef CICCIO
img_read_tzup_icon(char * filename)1566 IMAGE *img_read_tzup_icon(char *filename) {
1567 TIFF *tfp;
1568 IMAGE *image = NIL;
1569 TZUP_FIELDS tzup_f;
1570 char pltname[1024];
1571 USHORT *palette; /* [TOONZPALETTE_COUNT] */
1572 int max_n_colors, max_n_pencils;
1573
1574 Silent_tiff_print_error = 1;
1575 Tiff_ignore_missing_internal_colormap = 1;
1576 tfp = TIFFOpen(filename, "r");
1577 if (!tfp) return NIL;
1578
1579 if (!get_tzup_fields(tfp, &tzup_f)) goto bad;
1580
1581 image = new_img();
1582 if (!image) goto bad;
1583
1584 image->type = (tzup_f.bits_per_sample == 32) ? CMAPPED24 : CMAPPED;
1585 image->pixmap.xsize = tzup_f.xsize;
1586 image->pixmap.ysize = tzup_f.ysize;
1587 image->pixmap.xSBsize = tzup_f.xSBsize;
1588 image->pixmap.ySBsize = tzup_f.ySBsize;
1589 image->pixmap.xD = tzup_f.x0;
1590 image->pixmap.yD = tzup_f.y0;
1591
1592 get_plt_name(filename, pltname);
1593 image->cmap.name = strsave(pltname);
1594
1595 if (!TIFFGetField(tfp, TIFFTAG_TOONZPALETTE, &palette)) {
1596 image->cmap.info = Tcm_old_default_info;
1597 } else {
1598 /*image->cmap.info.tone_offs = palette[3]; */
1599 image->cmap.info.tone_bits = palette[4];
1600 image->cmap.info.color_offs = palette[5];
1601 image->cmap.info.color_bits = palette[6];
1602 image->cmap.info.pencil_offs = palette[7];
1603 image->cmap.info.pencil_bits = palette[8];
1604 image->cmap.info.offset_mask = palette[9];
1605 image->cmap.info.n_tones = 1 << palette[4];
1606 image->cmap.info.n_colors = palette[10];
1607 image->cmap.info.n_pencils = palette[11];
1608 image->cmap.info.default_val =
1609 (image->cmap.info.n_tones - 1) | image->cmap.info.offset_mask;
1610 }
1611
1612 /* estendo la palette */
1613
1614 max_n_colors = 1 << image->cmap.info.color_bits;
1615 max_n_pencils = 1 << image->cmap.info.pencil_bits;
1616 if (max_n_colors > image->cmap.info.n_colors ||
1617 max_n_pencils > image->cmap.info.n_pencils) {
1618 image->cmap.info.n_colors = max_n_colors;
1619 image->cmap.info.n_pencils = max_n_pencils;
1620 image->cmap.color_n = image->cmap.info.n_colors;
1621 image->cmap.pencil_n = image->cmap.info.n_pencils;
1622 }
1623
1624 if (!get_icon(tfp, image)) {
1625 // tmsg_error("unable to read icon image of file %s", filename);
1626 goto bad;
1627 }
1628 Silent_tiff_print_error = 0;
1629 Tiff_ignore_missing_internal_colormap = 0;
1630 TIFFClose(tfp);
1631 return image;
1632
1633 bad:
1634 if (image) free_img(image);
1635 Silent_tiff_print_error = 0;
1636 Tiff_ignore_missing_internal_colormap = 0;
1637 TIFFClose(tfp);
1638 return NIL;
1639 }
1640 #endif
1641
1642 /*===========================================================================*/
1643
get_tzup_fields(TIFF * tfp,TZUP_FIELDS * tzup_f)1644 static int get_tzup_fields(TIFF *tfp, TZUP_FIELDS *tzup_f) {
1645 if (!get_bits_per_sample(tfp, &tzup_f->bits_per_sample)) {
1646 // tmsg_error("can't handle %d-bit images", tzup_f->bits_per_sample);
1647 goto bad;
1648 }
1649 if (!get_samples_per_pixel(tfp, &tzup_f->samples_per_pixel)) {
1650 // tmsg_error("can't handle %d-channel images", tzup_f->samples_per_pixel);
1651 goto bad;
1652 }
1653 if (!get_image_sizes(tfp, &tzup_f->xSBsize, &tzup_f->ySBsize)) {
1654 // tmsg_error("bad image size %dx%d reading .tz(up) file",
1655 // tzup_f->xSBsize, tzup_f->ySBsize);
1656 goto bad;
1657 }
1658 if (!get_photometric(tfp, &tzup_f->photometric)) {
1659 // tmsg_error("bad photometric interpretation reading .tz(up) file");
1660 goto bad;
1661 }
1662 if (!get_resolutions(tfp, &tzup_f->x_dpi, &tzup_f->y_dpi)) {
1663 // tmsg_error("bad resolutions xres=%lf, yres=%lf reading .tz(up) file",
1664 // tzup_f->x_dpi, tzup_f->y_dpi);
1665 goto bad;
1666 }
1667 get_image_offsets_and_dimensions(tfp, tzup_f->xSBsize, tzup_f->ySBsize,
1668 &tzup_f->x0, &tzup_f->y0, &tzup_f->xsize,
1669 &tzup_f->ysize, &tzup_f->h_pos,
1670 &tzup_f->extra_mask, &tzup_f->edu_file);
1671 return TRUE;
1672
1673 bad:
1674 return FALSE;
1675 }
1676
1677 /*---------------------------------------------------------------------------*/
1678
get_bits_per_sample(TIFF * tif,USHORT * bps)1679 static int get_bits_per_sample(TIFF *tif, USHORT *bps) {
1680 if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, bps)) {
1681 *bps = 0;
1682 return FALSE;
1683 }
1684 switch (*bps) {
1685 CASE 1 : __OR 2 : __OR 4 : __OR 8 : __OR 16 : __OR 32 : return TRUE;
1686 }
1687 return FALSE;
1688 }
1689
1690 /*---------------------------------------------------------------------------*/
1691
get_samples_per_pixel(TIFF * tif,USHORT * spp)1692 static int get_samples_per_pixel(TIFF *tif, USHORT *spp) {
1693 if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp)) {
1694 *spp = 0;
1695 return FALSE;
1696 }
1697 switch (*spp) { CASE 1 : __OR 3 : __OR 4 : return TRUE; }
1698 return FALSE;
1699 }
1700
1701 /*---------------------------------------------------------------------------*/
1702
get_image_sizes(TIFF * tif,int * xsize,int * ysize)1703 static int get_image_sizes(TIFF *tif, int *xsize, int *ysize) {
1704 *ysize = 0;
1705 if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, xsize)) return FALSE;
1706 if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, ysize)) return FALSE;
1707 return TRUE;
1708 }
1709
1710 /*---------------------------------------------------------------------------*/
1711
get_image_offsets_and_dimensions(TIFF * tfp,int xSBsize,int ySBsize,int * x0,int * y0,int * xsize,int * ysize,double * h_pos,UCHAR * extra_mask,TBOOL * edu_file)1712 static void get_image_offsets_and_dimensions(TIFF *tfp, int xSBsize,
1713 int ySBsize, int *x0, int *y0,
1714 int *xsize, int *ysize,
1715 double *h_pos, UCHAR *extra_mask,
1716 TBOOL *edu_file) {
1717 USHORT *window, orientation;
1718 float xposition, dpi;
1719 // int i;
1720
1721 if (!TIFFGetField(tfp, TIFFTAG_TOONZWINDOW, &window)) {
1722 *x0 = 0;
1723 *y0 = 0;
1724 *xsize = xSBsize;
1725 *ysize = ySBsize;
1726 *extra_mask = 0;
1727
1728 *edu_file = FALSE;
1729 } else {
1730 *x0 = window[0];
1731 *y0 = window[1];
1732 *xsize = window[2];
1733 *ysize = window[3];
1734 if (*xsize == 0) *xsize = xSBsize + *x0;
1735 if (*ysize == 0) *ysize = ySBsize + *y0;
1736 *extra_mask = Read_with_extra ? window[4] : 0;
1737
1738 *edu_file = window[TOONZWINDOW_COUNT - 1] & 1;
1739 }
1740 if (!TIFFGetField(tfp, TIFFTAG_XPOSITION, &xposition)) xposition = 8.0;
1741 if (!TIFFGetField(tfp, TIFFTAG_ORIENTATION, &orientation))
1742 orientation = ORIENTATION_TOPLEFT;
1743 switch (orientation) {
1744 CASE ORIENTATION_BOTLEFT
1745 : __OR ORIENTATION_BOTRIGHT
1746 : __OR ORIENTATION_TOPLEFT
1747 : __OR ORIENTATION_TOPRIGHT
1748 : if (!TIFFGetField(tfp, TIFFTAG_XRESOLUTION, &dpi)) dpi = 0.0;
1749 CASE ORIENTATION_LEFTBOT
1750 : __OR ORIENTATION_RIGHTBOT
1751 : __OR ORIENTATION_LEFTTOP
1752 : __OR ORIENTATION_RIGHTTOP
1753 : if (!TIFFGetField(tfp, TIFFTAG_YRESOLUTION, &dpi)) dpi = 0.0;
1754 }
1755 *h_pos = (xposition - 8.0) * dpi;
1756 }
1757
1758 /*---------------------------------------------------------------------------*/
1759
get_photometric(TIFF * tif,USHORT * pm)1760 static int get_photometric(TIFF *tif, USHORT *pm) {
1761 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, pm)) return FALSE;
1762 return TRUE;
1763 }
1764
1765 /*---------------------------------------------------------------------------*/
1766
get_resolutions(TIFF * tif,double * x_dpi,double * y_dpi)1767 static int get_resolutions(TIFF *tif, double *x_dpi, double *y_dpi) {
1768 float xdpi, ydpi;
1769 // USHORT resunit;
1770
1771 if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xdpi) ||
1772 !TIFFGetField(tif, TIFFTAG_YRESOLUTION, &ydpi)) {
1773 *x_dpi = *y_dpi = 0.0;
1774 return FALSE;
1775 }
1776 *x_dpi = (double)xdpi;
1777 *y_dpi = (double)ydpi;
1778 return TRUE;
1779 }
1780
1781 /*---------------------------------------------------------------------------*/
1782
get_orientation(TIFF * tif,int * orientation)1783 static int get_orientation(TIFF *tif, int *orientation) {
1784 if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation)) return FALSE;
1785 return TRUE;
1786 }
1787
1788 /*---------------------------------------------------------------------------*/
1789
get_rows_per_strip(TIFF * tif,long * rowperstrip)1790 static int get_rows_per_strip(TIFF *tif, long *rowperstrip) {
1791 if (!TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowperstrip)) return FALSE;
1792 return TRUE;
1793 }
1794
1795 /*---------------------------------------------------------------------------*/
1796
get_compression(TIFF * tif,int * compression)1797 static int get_compression(TIFF *tif, int *compression) {
1798 if (!TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression)) return FALSE;
1799 return TRUE;
1800 }
1801
1802 /*---------------------------------------------------------------------------*/
1803
get_tag_software(TIFF * tif,char * tag_software)1804 static int get_tag_software(TIFF *tif, char *tag_software) {
1805 if (!TIFFGetField(tif, TIFFTAG_SOFTWARE, tag_software)) return FALSE;
1806 return TRUE;
1807 }
1808
1809 /*---------------------------------------------------------------------------*/
1810
get_planarconfig(TIFF * tif,USHORT * planarconfig)1811 static void get_planarconfig(TIFF *tif, USHORT *planarconfig) {
1812 TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
1813 }
1814
1815 /*---------------------------------------------------------------------------*/
1816
get_history(TIFF * tif,char ** history)1817 static int get_history(TIFF *tif, char **history) {
1818 if (!TIFFGetField(tif, TIFFTAG_TOONZHISTORY, history)) return FALSE;
1819 //*history = strsave(*history);
1820 return TRUE;
1821 }
1822
1823 /*---------------------------------------------------------------------------*/
1824
get_image(TIFF * tf,IMAGE * image)1825 static int get_image(TIFF *tf, IMAGE *image) {
1826 USHORT planarconfig;
1827 // int i;
1828
1829 TIFFGetField(tf, TIFFTAG_PLANARCONFIG, &planarconfig);
1830 if (planarconfig == PLANARCONFIG_SEPARATE) {
1831 // tmsg_error("separate buffer image not supported yet in .tz(up) files");
1832 return FALSE;
1833 }
1834 switch (image->type) {
1835 CASE CMAPPED : return get_image_contig_16(tf, image);
1836 CASE CMAPPED24 : return get_image_contig_24(tf, image);
1837 DEFAULT:
1838 abort();
1839 }
1840 return FALSE;
1841 }
1842
1843 /*---------------------------------------------------------------------------*/
1844
get_image_contig_16(TIFF * tf,IMAGE * image)1845 static int get_image_contig_16(TIFF *tf, IMAGE *image) {
1846 int x, y, x0, y0, x1, y1, lx, ly, xsize, ysize, wrap;
1847 USHORT *buf, *pix, default_val;
1848 TBOOL swap_needed;
1849
1850 swap_needed = scanline_needs_swapping(tf);
1851
1852 x0 = image->pixmap.xD;
1853 y0 = image->pixmap.yD;
1854 lx = image->pixmap.xSBsize;
1855 ly = image->pixmap.ySBsize;
1856 x1 = x0 + lx - 1;
1857 y1 = y0 + ly - 1;
1858 xsize = image->pixmap.xsize;
1859 ysize = image->pixmap.ysize;
1860 wrap = image->pixmap.xsize;
1861 buf = image->pixmap.buffer;
1862 default_val = image->cmap.info.default_val;
1863 for (y = 0; y < y0; y++) {
1864 pix = buf + y * wrap;
1865 for (x = 0; x < xsize; x++) *pix++ = default_val;
1866 }
1867 for (; y <= y1; y++) {
1868 pix = buf + y * wrap;
1869 for (x = 0; x < x0; x++) *pix++ = default_val;
1870 if (TIFFReadScanline(tf, (UCHAR *)pix, y - y0, 0) < 0) {
1871 static int gia_dato = FALSE;
1872 if (!gia_dato) {
1873 // tmsg_error("bad data read on line %d", y);
1874 gia_dato = TRUE;
1875 }
1876 memset(pix, 0, lx * sizeof(*pix));
1877 }
1878 if (swap_needed) TIFFSwabArrayOfShort((USHORT *)pix, lx);
1879 pix += lx;
1880 for (x = x1 + 1; x < xsize; x++) *pix++ = default_val;
1881 }
1882 for (; y < ysize; y++) {
1883 pix = buf + y * wrap;
1884 for (x = 0; x < xsize; x++) *pix++ = default_val;
1885 }
1886 return TRUE;
1887 }
1888
1889 /*---------------------------------------------------------------------------*/
1890
get_image_contig_24(TIFF * tf,IMAGE * image)1891 static int get_image_contig_24(TIFF *tf, IMAGE *image) {
1892 int x, y, x0, y0, x1, y1, lx, ly, xsize, ysize, wrap;
1893 ULONG *buf, *pix, default_val;
1894 TBOOL swap_needed;
1895
1896 swap_needed = scanline_needs_swapping(tf);
1897
1898 x0 = image->pixmap.xD;
1899 y0 = image->pixmap.yD;
1900 lx = image->pixmap.xSBsize;
1901 ly = image->pixmap.ySBsize;
1902 x1 = x0 + lx - 1;
1903 y1 = y0 + ly - 1;
1904 xsize = image->pixmap.xsize;
1905 ysize = image->pixmap.ysize;
1906 wrap = image->pixmap.xsize;
1907 buf = (ULONG *)image->pixmap.buffer;
1908 default_val = image->cmap.info.default_val;
1909 for (y = 0; y < y0; y++) {
1910 pix = buf + y * wrap;
1911 for (x = 0; x < xsize; x++) *pix++ = default_val;
1912 }
1913 for (; y <= y1; y++) {
1914 pix = buf + y * wrap;
1915 for (x = 0; x < x0; x++) *pix++ = default_val;
1916 if (TIFFReadScanline(tf, (UCHAR *)pix, y - y0, 0) < 0) {
1917 static int gia_dato = FALSE;
1918 if (!gia_dato) {
1919 // tmsg_error("bad data read on line %d", y);
1920 gia_dato = TRUE;
1921 }
1922 memset(pix, 0, lx * sizeof(*pix));
1923 }
1924 if (swap_needed) TIFFSwabArrayOfLong((TUINT32 *)pix, lx);
1925 pix += lx;
1926 for (x = x1 + 1; x < xsize; x++) *pix++ = default_val;
1927 }
1928 for (; y < ysize; y++) {
1929 pix = buf + y * wrap;
1930 for (x = 0; x < xsize; x++) *pix++ = default_val;
1931 }
1932 return TRUE;
1933 }
1934
1935 /*---------------------------------------------------------------------------*/
1936
get_icon_16(TIFF * tfp,IMAGE * image)1937 static int get_icon_16(TIFF *tfp, IMAGE *image) {
1938 int lx, ly;
1939 UCHAR *buffer;
1940 USHORT *icon_buffer;
1941 int scanline, row;
1942 TBOOL swap_needed;
1943
1944 if (!TIFFReadDirectory(tfp)) return FALSE;
1945 if (!get_image_sizes(tfp, &lx, &ly)) return FALSE;
1946 swap_needed = scanline_needs_swapping(tfp);
1947
1948 scanline = TIFFScanlineSize(tfp);
1949
1950 icon_buffer = new USHORT[lx * ly];
1951
1952 if (!icon_buffer) return FALSE;
1953 image->icon.buffer = icon_buffer;
1954 image->icon.xsize = lx;
1955 image->icon.ysize = ly;
1956 image->icon.xSBsize = lx;
1957 image->icon.ySBsize = ly;
1958 image->icon.xD = 0;
1959 image->icon.yD = 0;
1960
1961 buffer = (UCHAR *)image->icon.buffer;
1962 for (row = 0; row < image->icon.ysize; row++) {
1963 if (TIFFReadScanline(tfp, buffer, row, 0) < 0) {
1964 // tmsg_error("bad data read on line %d", row);
1965 return FALSE;
1966 }
1967 if (swap_needed) TIFFSwabArrayOfShort((USHORT *)buffer, lx);
1968
1969 buffer += scanline;
1970 }
1971 return TRUE;
1972 }
1973
1974 /*---------------------------------------------------------------------------*/
1975
get_icon_24(TIFF * tfp,IMAGE * image)1976 static int get_icon_24(TIFF *tfp, IMAGE *image) {
1977 int lx, ly;
1978 UCHAR *buffer;
1979 ULONG *icon_buffer;
1980 int scanline, row;
1981 TBOOL swap_needed;
1982
1983 if (!TIFFReadDirectory(tfp)) return FALSE;
1984 if (!get_image_sizes(tfp, &lx, &ly)) return FALSE;
1985 swap_needed = scanline_needs_swapping(tfp);
1986
1987 scanline = TIFFScanlineSize(tfp);
1988
1989 icon_buffer = new ULONG[lx * ly];
1990 if (!icon_buffer) return FALSE;
1991 image->icon.buffer = (USHORT *)icon_buffer;
1992 image->icon.xsize = lx;
1993 image->icon.ysize = ly;
1994 image->icon.xSBsize = lx;
1995 image->icon.ySBsize = ly;
1996 image->icon.xD = 0;
1997 image->icon.yD = 0;
1998
1999 buffer = (UCHAR *)image->icon.buffer;
2000 for (row = 0; row < image->icon.ysize; row++) {
2001 if (TIFFReadScanline(tfp, buffer, row, 0) < 0) {
2002 // tmsg_error("bad data read on line %d", row);
2003 return FALSE;
2004 }
2005 if (swap_needed) TIFFSwabArrayOfLong((TUINT32 *)buffer, lx);
2006
2007 buffer += scanline;
2008 }
2009 return TRUE;
2010 }
2011
2012 /*---------------------------------------------------------------------------*/
2013
get_icon(TIFF * tfp,IMAGE * image)2014 static int get_icon(TIFF *tfp, IMAGE *image) {
2015 switch (image->type) {
2016 CASE CMAPPED : return get_icon_16(tfp, image);
2017 CASE CMAPPED24 : return get_icon_24(tfp, image);
2018 DEFAULT:
2019 abort();
2020 }
2021 return FALSE;
2022 }
2023
2024 /*---------------------------------------------------------------------------*/
2025
get_extra(TIFF * tfp,IMAGE * image)2026 static int get_extra(TIFF *tfp, IMAGE *image) {
2027 int x, y, x0, y0, x1, y1, lx, ly, xsize, ysize, wrap;
2028 UCHAR *buf, *pix;
2029
2030 if (!TIFFReadDirectory(tfp)) return FALSE;
2031
2032 x0 = image->pixmap.xD;
2033 y0 = image->pixmap.yD;
2034 lx = image->pixmap.xSBsize;
2035 ly = image->pixmap.ySBsize;
2036 x1 = x0 + lx - 1;
2037 y1 = y0 + ly - 1;
2038 xsize = image->pixmap.xsize;
2039 ysize = image->pixmap.ysize;
2040 wrap = image->pixmap.xsize;
2041 buf = image->pixmap.extra;
2042 for (y = 0; y < y0; y++) {
2043 pix = buf + y * wrap;
2044 for (x = 0; x < xsize; x++) *pix++ = 0;
2045 }
2046 for (; y <= y1; y++) {
2047 pix = buf + y * wrap;
2048 for (x = 0; x < x0; x++) *pix++ = 0;
2049 if (TIFFReadScanline(tfp, (UCHAR *)pix, y - y0, 0) < 0) {
2050 static int gia_dato = FALSE;
2051 if (!gia_dato) {
2052 // tmsg_error("bad data read on extra line %d", y);
2053 gia_dato = TRUE;
2054 }
2055 memset(pix, 0, lx * sizeof(*pix));
2056 }
2057 pix += lx;
2058 for (x = x1 + 1; x < xsize; x++) *pix++ = 0;
2059 }
2060 for (; y < ysize; y++) {
2061 pix = buf + y * wrap;
2062 for (x = 0; x < xsize; x++) *pix++ = 0;
2063 }
2064 return TRUE;
2065 }
2066
2067 /*---------------------------------------------------------------------------*/
2068
get_plt_name(char * filename,char * pltname)2069 static void get_plt_name(char *filename, char *pltname) {
2070 // sprintf (pltname, "%s.plt", tim_get_name_nodot((const char*)filename));
2071 }
2072
2073 /*---------------------------------------------------------------------------*/
2074
clear_image_buffer_16(IMAGE * img,USHORT bg_val)2075 static void clear_image_buffer_16(IMAGE *img, USHORT bg_val) {
2076 clear_image_region_buffer_16(img->pixmap.buffer, 0, 0, img->pixmap.xsize,
2077 img->pixmap.ysize, img->pixmap.xsize, bg_val);
2078 }
2079
2080 /*---------------------------------------------------------------------------*/
2081
clear_image_buffer_24(IMAGE * img,ULONG bg_val)2082 static void clear_image_buffer_24(IMAGE *img, ULONG bg_val) {
2083 clear_image_region_buffer_24((ULONG *)img->pixmap.buffer, 0, 0,
2084 img->pixmap.xsize, img->pixmap.ysize,
2085 img->pixmap.xsize, bg_val);
2086 }
2087
2088 /*---------------------------------------------------------------------------*/
2089
clear_extra(IMAGE * img,UCHAR bg_val)2090 static void clear_extra(IMAGE *img, UCHAR bg_val) {
2091 clear_extra_region(img->pixmap.extra, 0, 0, img->pixmap.xsize,
2092 img->pixmap.ysize, img->pixmap.xsize, bg_val);
2093 }
2094
2095 /*---------------------------------------------------------------------------*/
2096
clear_image_region_buffer_16(USHORT * buffer,int x0,int y0,int xsize,int ysize,int wrap_x,USHORT bg_val)2097 static void clear_image_region_buffer_16(USHORT *buffer, int x0, int y0,
2098 int xsize, int ysize, int wrap_x,
2099 USHORT bg_val) {
2100 USHORT *tmp = new USHORT[xsize];
2101 int x, y, bytes;
2102
2103 if (!tmp) return;
2104
2105 for (x = 0; x < xsize; x++) tmp[x] = bg_val;
2106
2107 bytes = xsize * sizeof(USHORT);
2108 buffer += x0 + y0 * wrap_x;
2109 for (y = 0; y < ysize; y++) {
2110 memcpy(buffer, tmp, bytes);
2111 buffer += wrap_x;
2112 }
2113 delete[] tmp;
2114 }
2115
2116 /*---------------------------------------------------------------------------*/
2117
clear_image_region_buffer_24(ULONG * buffer,int x0,int y0,int xsize,int ysize,int wrap_x,ULONG bg_val)2118 static void clear_image_region_buffer_24(ULONG *buffer, int x0, int y0,
2119 int xsize, int ysize, int wrap_x,
2120 ULONG bg_val) {
2121 ULONG *tmp = new ULONG[xsize];
2122 int x, y, bytes;
2123
2124 if (!tmp) return;
2125
2126 for (x = 0; x < xsize; x++) tmp[x] = bg_val;
2127
2128 bytes = xsize * sizeof(ULONG);
2129 buffer += x0 + y0 * wrap_x;
2130 for (y = 0; y < ysize; y++) {
2131 memcpy(buffer, tmp, bytes);
2132 buffer += wrap_x;
2133 }
2134 delete tmp;
2135 }
2136
2137 /*---------------------------------------------------------------------------*/
2138
clear_extra_region(UCHAR * extra,int x0,int y0,int xsize,int ysize,int wrap_x,UCHAR bg_val)2139 static void clear_extra_region(UCHAR *extra, int x0, int y0, int xsize,
2140 int ysize, int wrap_x, UCHAR bg_val) {
2141 int y;
2142
2143 extra += x0 + y0 * wrap_x;
2144 for (y = 0; y < ysize; y++) {
2145 memset(extra, bg_val, xsize);
2146 extra += wrap_x;
2147 }
2148 }
2149