]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/tiff2rgba.c
4 * Copyright (c) 1991-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
27 #include "tif_config.h"
39 #define streq(a,b) (strcmp(a,b) == 0)
40 #define CopyField(tag, v) \
41 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
44 #define howmany(x, y) (((x)+((y)-1))/(y))
46 #define roundup(x, y) (howmany(x,y)*((uint32)(y)))
48 uint16 compression
= COMPRESSION_PACKBITS
;
49 uint32 rowsperstrip
= (uint32
) -1;
50 int process_by_block
= 0; /* default is whole image at once */
54 static int tiffcvt(TIFF
* in
, TIFF
* out
);
55 static void usage(int code
);
58 main(int argc
, char* argv
[])
65 while ((c
= getopt(argc
, argv
, "c:r:t:bn")) != -1)
72 if (streq(optarg
, "none"))
73 compression
= COMPRESSION_NONE
;
74 else if (streq(optarg
, "packbits"))
75 compression
= COMPRESSION_PACKBITS
;
76 else if (streq(optarg
, "lzw"))
77 compression
= COMPRESSION_LZW
;
78 else if (streq(optarg
, "jpeg"))
79 compression
= COMPRESSION_JPEG
;
80 else if (streq(optarg
, "zip"))
81 compression
= COMPRESSION_DEFLATE
;
87 rowsperstrip
= atoi(optarg
);
91 rowsperstrip
= atoi(optarg
);
103 if (argc
- optind
< 2)
106 out
= TIFFOpen(argv
[argc
-1], "w");
110 for (; optind
< argc
-1; optind
++) {
111 in
= TIFFOpen(argv
[optind
], "r");
114 if (!tiffcvt(in
, out
) ||
115 !TIFFWriteDirectory(out
)) {
116 (void) TIFFClose(out
);
119 } while (TIFFReadDirectory(in
));
120 (void) TIFFClose(in
);
123 (void) TIFFClose(out
);
128 cvt_by_tile( TIFF
*in
, TIFF
*out
)
131 uint32
* raster
; /* retrieve RGBA image */
132 uint32 width
, height
; /* image width & height */
133 uint32 tile_width
, tile_height
;
138 TIFFGetField(in
, TIFFTAG_IMAGEWIDTH
, &width
);
139 TIFFGetField(in
, TIFFTAG_IMAGELENGTH
, &height
);
141 if( !TIFFGetField(in
, TIFFTAG_TILEWIDTH
, &tile_width
)
142 || !TIFFGetField(in
, TIFFTAG_TILELENGTH
, &tile_height
) ) {
143 TIFFError(TIFFFileName(in
), "Source image not tiled");
147 TIFFSetField(out
, TIFFTAG_TILEWIDTH
, tile_width
);
148 TIFFSetField(out
, TIFFTAG_TILELENGTH
, tile_height
);
151 * Allocate tile buffer
153 raster
= (uint32
*)_TIFFmalloc(tile_width
* tile_height
* sizeof (uint32
));
155 TIFFError(TIFFFileName(in
), "No space for raster buffer");
160 * Allocate a scanline buffer for swapping during the vertical
163 wrk_line
= (uint32
*)_TIFFmalloc(tile_width
* sizeof (uint32
));
165 TIFFError(TIFFFileName(in
), "No space for raster scanline buffer");
170 * Loop over the tiles.
172 for( row
= 0; ok
&& row
< height
; row
+= tile_height
)
174 for( col
= 0; ok
&& col
< width
; col
+= tile_width
)
178 /* Read the tile into an RGBA array */
179 if (!TIFFReadRGBATile(in
, col
, row
, raster
)) {
185 * For some reason the TIFFReadRGBATile() function chooses the
186 * lower left corner as the origin. Vertically mirror scanlines.
188 for( i_row
= 0; i_row
< tile_height
/ 2; i_row
++ )
190 uint32
*top_line
, *bottom_line
;
192 top_line
= raster
+ tile_width
* i_row
;
193 bottom_line
= raster
+ tile_width
* (tile_height
-i_row
-1);
195 _TIFFmemcpy(wrk_line
, top_line
, 4*tile_width
);
196 _TIFFmemcpy(top_line
, bottom_line
, 4*tile_width
);
197 _TIFFmemcpy(bottom_line
, wrk_line
, 4*tile_width
);
201 * Write out the result in a tile.
204 if( TIFFWriteEncodedTile( out
,
205 TIFFComputeTile( out
, col
, row
, 0, 0),
207 4 * tile_width
* tile_height
) == -1 )
216 _TIFFfree( wrk_line
);
222 cvt_by_strip( TIFF
*in
, TIFF
*out
)
225 uint32
* raster
; /* retrieve RGBA image */
226 uint32 width
, height
; /* image width & height */
231 TIFFGetField(in
, TIFFTAG_IMAGEWIDTH
, &width
);
232 TIFFGetField(in
, TIFFTAG_IMAGELENGTH
, &height
);
234 if( !TIFFGetField(in
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
) ) {
235 TIFFError(TIFFFileName(in
), "Source image not in strips");
239 TIFFSetField(out
, TIFFTAG_ROWSPERSTRIP
, rowsperstrip
);
242 * Allocate strip buffer
244 raster
= (uint32
*)_TIFFmalloc(width
* rowsperstrip
* sizeof (uint32
));
246 TIFFError(TIFFFileName(in
), "No space for raster buffer");
251 * Allocate a scanline buffer for swapping during the vertical
254 wrk_line
= (uint32
*)_TIFFmalloc(width
* sizeof (uint32
));
256 TIFFError(TIFFFileName(in
), "No space for raster scanline buffer");
261 * Loop over the strips.
263 for( row
= 0; ok
&& row
< height
; row
+= rowsperstrip
)
265 int rows_to_write
, i_row
;
267 /* Read the strip into an RGBA array */
268 if (!TIFFReadRGBAStrip(in
, row
, raster
)) {
274 * Figure out the number of scanlines actually in this strip.
276 if( row
+ rowsperstrip
> height
)
277 rows_to_write
= height
- row
;
279 rows_to_write
= rowsperstrip
;
282 * For some reason the TIFFReadRGBAStrip() function chooses the
283 * lower left corner as the origin. Vertically mirror scanlines.
286 for( i_row
= 0; i_row
< rows_to_write
/ 2; i_row
++ )
288 uint32
*top_line
, *bottom_line
;
290 top_line
= raster
+ width
* i_row
;
291 bottom_line
= raster
+ width
* (rows_to_write
-i_row
-1);
293 _TIFFmemcpy(wrk_line
, top_line
, 4*width
);
294 _TIFFmemcpy(top_line
, bottom_line
, 4*width
);
295 _TIFFmemcpy(bottom_line
, wrk_line
, 4*width
);
299 * Write out the result in a strip
302 if( TIFFWriteEncodedStrip( out
, row
/ rowsperstrip
, raster
,
303 4 * rows_to_write
* width
) == -1 )
311 _TIFFfree( wrk_line
);
319 * read the whole image into one big RGBA buffer and then write out
320 * strips from that. This is using the traditional TIFFReadRGBAImage()
325 cvt_whole_image( TIFF
*in
, TIFF
*out
)
328 uint32
* raster
; /* retrieve RGBA image */
329 uint32 width
, height
; /* image width & height */
332 TIFFGetField(in
, TIFFTAG_IMAGEWIDTH
, &width
);
333 TIFFGetField(in
, TIFFTAG_IMAGELENGTH
, &height
);
335 rowsperstrip
= TIFFDefaultStripSize(out
, rowsperstrip
);
336 TIFFSetField(out
, TIFFTAG_ROWSPERSTRIP
, rowsperstrip
);
338 raster
= (uint32
*)_TIFFmalloc(width
* height
* sizeof (uint32
));
340 TIFFError(TIFFFileName(in
), "No space for raster buffer");
344 /* Read the image in one chunk into an RGBA array */
345 if (!TIFFReadRGBAImageOriented(in
, width
, height
, raster
,
346 ORIENTATION_TOPLEFT
, 0)) {
352 ** Do we want to strip away alpha components?
356 int pixel_count
= width
* height
;
357 unsigned char *src
, *dst
;
359 src
= (unsigned char *) raster
;
360 dst
= (unsigned char *) raster
;
361 while( pixel_count
> 0 )
371 /* Write out the result in strips */
373 for( row
= 0; row
< height
; row
+= rowsperstrip
)
375 unsigned char * raster_strip
;
381 raster_strip
= ((unsigned char *) raster
) + 3 * row
* width
;
386 raster_strip
= (unsigned char *) (raster
+ row
* width
);
390 if( row
+ rowsperstrip
> height
)
391 rows_to_write
= height
- row
;
393 rows_to_write
= rowsperstrip
;
395 if( TIFFWriteEncodedStrip( out
, row
/ rowsperstrip
, raster_strip
,
396 bytes_per_pixel
* rows_to_write
* width
) == -1 )
410 tiffcvt(TIFF
* in
, TIFF
* out
)
412 uint32 width
, height
; /* image width & height */
419 TIFFGetField(in
, TIFFTAG_IMAGEWIDTH
, &width
);
420 TIFFGetField(in
, TIFFTAG_IMAGELENGTH
, &height
);
422 CopyField(TIFFTAG_SUBFILETYPE
, longv
);
423 TIFFSetField(out
, TIFFTAG_IMAGEWIDTH
, width
);
424 TIFFSetField(out
, TIFFTAG_IMAGELENGTH
, height
);
425 TIFFSetField(out
, TIFFTAG_BITSPERSAMPLE
, 8);
426 TIFFSetField(out
, TIFFTAG_COMPRESSION
, compression
);
427 TIFFSetField(out
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_RGB
);
429 CopyField(TIFFTAG_FILLORDER
, shortv
);
430 TIFFSetField(out
, TIFFTAG_ORIENTATION
, ORIENTATION_TOPLEFT
);
433 TIFFSetField(out
, TIFFTAG_SAMPLESPERPIXEL
, 3);
435 TIFFSetField(out
, TIFFTAG_SAMPLESPERPIXEL
, 4);
439 v
[0] = EXTRASAMPLE_ASSOCALPHA
;
440 TIFFSetField(out
, TIFFTAG_EXTRASAMPLES
, 1, v
);
443 CopyField(TIFFTAG_XRESOLUTION
, floatv
);
444 CopyField(TIFFTAG_YRESOLUTION
, floatv
);
445 CopyField(TIFFTAG_RESOLUTIONUNIT
, shortv
);
446 TIFFSetField(out
, TIFFTAG_PLANARCONFIG
, PLANARCONFIG_CONTIG
);
447 TIFFSetField(out
, TIFFTAG_SOFTWARE
, TIFFGetVersion());
448 CopyField(TIFFTAG_DOCUMENTNAME
, stringv
);
450 if( process_by_block
&& TIFFIsTiled( in
) )
451 return( cvt_by_tile( in
, out
) );
452 else if( process_by_block
)
453 return( cvt_by_strip( in
, out
) );
455 return( cvt_whole_image( in
, out
) );
458 static char* stuff
[] = {
459 "usage: tiff2rgba [-c comp] [-r rows] [-b] input... output",
460 "where comp is one of the following compression algorithms:",
461 " jpeg\t\tJPEG encoding",
462 " zip\t\tLempel-Ziv & Welch encoding",
463 " lzw\t\tLempel-Ziv & Welch encoding",
464 " packbits\tPackBits encoding",
465 " none\t\tno compression",
466 "and the other options are:",
468 " -b (progress by block rather than as a whole image)",
469 " -n don't emit alpha component.",
480 fprintf(stderr
, "%s\n\n", TIFFGetVersion());
481 for (i
= 0; stuff
[i
] != NULL
; i
++)
482 fprintf(stderr
, "%s\n", stuff
[i
]);
486 /* vim: set ts=8 sts=8 sw=8 noet: */