Added ability to create multipage TIFFs from the list of input files as per

bug: http://bugzilla.remotesensing.org/show_bug.cgi?id=1077
This commit is contained in:
Andrey Kiselev 2006-02-15 13:12:30 +00:00
parent b936f969d0
commit d4438d6fd4
2 changed files with 422 additions and 392 deletions

View File

@ -1,4 +1,4 @@
.\" $Id: bmp2tiff.1,v 1.4 2005-11-02 11:07:19 dron Exp $
.\" $Id: bmp2tiff.1,v 1.5 2006-02-15 13:12:30 dron Exp $
.\"
.\" Copyright (c) 2004, Andrey Kiselev <dron@remotesensing.org>
.\"
@ -32,13 +32,15 @@ file from a Microsoft Windows Device Independent Bitmap image file
[
.I options
]
.I input.bmp
.I input.bmp [input2.bmp ...]
.I output.tiff
.SH DESCRIPTION
.I bmp2tiff
converts a Microsoft Windows Device Independent Bitmap image file to
.SM TIFF.
By default, the
If several input BMP files are being specified the multipage
.SM TIFF
output file will be created. By default, the
.SM TIFF
image is created with data samples packed (\c
.IR PlanarConfiguration =1),

View File

@ -1,4 +1,4 @@
/* $Id: bmp2tiff.c,v 1.18 2006-01-11 17:03:43 fwarmerdam Exp $
/* $Id: bmp2tiff.c,v 1.19 2006-02-15 13:12:54 dron Exp $
*
* Project: libtiff tools
* Purpose: Convert Windows BMP files in TIFF.
@ -228,7 +228,7 @@ main(int argc, char* argv[])
uint16 depth = 8; /* bits per pixel in input image */
uint32 rowsperstrip = (uint32) -1;
uint16 photometric = PHOTOMETRIC_MINISBLACK;
int fd;
int fd = 0;
struct stat instat;
char *outfilename = NULL, *infilename = NULL;
TIFF *out = NULL;
@ -267,7 +267,20 @@ main(int argc, char* argv[])
if (argc - optind < 2)
usage();
if (outfilename == NULL)
outfilename = argv[argc-1];
out = TIFFOpen(outfilename, "w");
if (out == NULL) {
TIFFError(infilename, "Cannot open file %s for output",
outfilename);
goto bad3;
}
while (optind < argc-1) {
infilename = argv[optind];
optind++;
fd = open(infilename, O_RDONLY|O_BINARY, 0);
if (fd < 0) {
TIFFError(infilename, "Cannot open input file");
@ -305,12 +318,15 @@ main(int argc, char* argv[])
bmp_type = BMPT_WIN4;
else if (info_hdr.iSize == BIH_OS21SIZE)
bmp_type = BMPT_OS21;
else if (info_hdr.iSize == BIH_OS22SIZE || info_hdr.iSize == 16)
else if (info_hdr.iSize == BIH_OS22SIZE
|| info_hdr.iSize == 16)
bmp_type = BMPT_OS22;
else
bmp_type = BMPT_WIN5;
if (bmp_type == BMPT_WIN4 || bmp_type == BMPT_WIN5 || bmp_type == BMPT_OS22) {
if (bmp_type == BMPT_WIN4
|| bmp_type == BMPT_WIN5
|| bmp_type == BMPT_OS22) {
read(fd, &info_hdr.iWidth, 4);
read(fd, &info_hdr.iHeight, 4);
read(fd, &info_hdr.iPlanes, 2);
@ -374,7 +390,8 @@ main(int argc, char* argv[])
if (info_hdr.iBitCount != 1 && info_hdr.iBitCount != 4 &&
info_hdr.iBitCount != 8 && info_hdr.iBitCount != 16 &&
info_hdr.iBitCount != 24 && info_hdr.iBitCount != 32) {
TIFFError(infilename, "Cannot process BMP file with bit count %d",
TIFFError(infilename,
"Cannot process BMP file with bit count %d",
info_hdr.iBitCount);
close(fd);
return 0;
@ -393,8 +410,10 @@ main(int argc, char* argv[])
photometric = PHOTOMETRIC_PALETTE;
/* Allocate memory for colour table and read it. */
if (info_hdr.iClrUsed)
clr_tbl_size = ((uint32)(1 << depth) < info_hdr.iClrUsed) ?
(uint32) (1 << depth) : info_hdr.iClrUsed;
clr_tbl_size =
((uint32)(1<<depth)<info_hdr.iClrUsed)
? (uint32) (1 << depth)
: info_hdr.iClrUsed;
else
clr_tbl_size = 1 << depth;
clr_tbl = (unsigned char *)
@ -460,15 +479,6 @@ main(int argc, char* argv[])
/* Create output file. */
/* -------------------------------------------------------------------- */
if (outfilename == NULL)
outfilename = argv[optind+1];
out = TIFFOpen(outfilename, "w");
if (out == NULL) {
TIFFError(infilename, "Cannot open file %s for output",
outfilename);
goto bad3;
}
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
@ -479,8 +489,10 @@ main(int argc, char* argv[])
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
if (red_tbl && green_tbl && blue_tbl)
TIFFSetField(out, TIFFTAG_COLORMAP, red_tbl, green_tbl, blue_tbl);
if (red_tbl && green_tbl && blue_tbl) {
TIFFSetField(out, TIFFTAG_COLORMAP,
red_tbl, green_tbl, blue_tbl);
}
if (compression == (uint16) -1)
compression = COMPRESSION_PACKBITS;
@ -508,20 +520,20 @@ main(int argc, char* argv[])
uint32 offset, size;
char *scanbuf;
/* XXX: Avoid integer overflow. We can calculate size in one
* step using
/* XXX: Avoid integer overflow. We can calculate size
* in one step using
*
* size = ((width * info_hdr.iBitCount + 31) & ~31) / 8
*
* formulae, but we should check for overflow conditions
* during calculation.
* formulae, but we should check for overflow
* conditions during calculation.
*/
size = width * info_hdr.iBitCount + 31;
if (!width || !info_hdr.iBitCount
|| (size - 31) / info_hdr.iBitCount != width ) {
TIFFError(infilename,
"Wrong image parameters; "
"can't allocate space for scanline buffer");
"Wrong image parameters; can't "
"allocate space for scanline buffer");
goto bad3;
}
size = (size & ~31) / 8;
@ -673,7 +685,9 @@ main(int argc, char* argv[])
_TIFFfree(comprbuf);
for (row = 0; row < length; row++) {
if (TIFFWriteScanline(out, uncomprbuf + (length - row - 1) * width, row, 0) < 0) {
if (TIFFWriteScanline(out,
uncomprbuf + (length - row - 1) * width,
row, 0) < 0) {
TIFFError(infilename,
"scanline %lu: Write error.\n",
(unsigned long) row);
@ -682,6 +696,20 @@ main(int argc, char* argv[])
_TIFFfree(uncomprbuf);
}
TIFFWriteDirectory(out);
if (blue_tbl) {
_TIFFfree(blue_tbl);
blue_tbl=NULL;
}
if (green_tbl) {
_TIFFfree(green_tbl);
green_tbl=NULL;
}
if (red_tbl) {
_TIFFfree(red_tbl);
red_tbl=NULL;
}
}
bad3:
if (blue_tbl)
@ -776,7 +804,7 @@ processCompressOptions(char* opt)
static char* stuff[] = {
"bmp2tiff --- convert Windows BMP files to TIFF",
"usage: bmp2tiff [options] input.bmp output.tif",
"usage: bmp2tiff [options] input.bmp [input2.bmp ...] output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
"",