
Thread
2004.10.09 08:00 "Re: [Tiff] Converting DIB to Tif using libtiff", by Andrey Kiselev
I was wondering if anyone knows of a general routine that will convert generic Windows DIB (given handle, etc) to a corresponding tiff file?
You can found the sample code attached. It was written for specific purpose to save the monocrome and grayscale images only, but it should give you a basic idea how to do the conversion.
Best regards,
Andrey
Andrey V. Kiselev
Home phone: +7 812 5274898 ICQ# 26871517
/******************************************************************************
* Project: ???
* Purpose: Routine to save Windows Device Dependent Bitmaps (DDB)
* as TIFF files.
* Author: Andrey Kiselev, dron@at1895.spb.edu
*
******************************************************************************
* Copyright (c) 2002, Andrey Kiselev <dron@at1895.spb.edu>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <tiffio.h>
/* Hack to test function without Windows development environment */
#ifndef __WIN32__
#define BYTE unsigned char
typedef struct tagBITMAP
{
int bmType;
int bmWidth;
int bmHeight;
int bmWidthBytes;
BYTE bmPlanes;
BYTE bmBitsPixel;
void *bmBits;
} BITMAP;
#else
#include <windows.h>
#endif
/******************************************************************************
* SaveAsTIFF() *
******************************************************************************
* SYNOPSIS:
*
* psBmp pointer to input BITMAP structure
* pszFilename pointer to string which containes path to output TIFF file
*
* Only 1-bit (monochrome) or 8-bit (grayscale) images supported.
* pszFilename file will be overwritten, caller responsible to check
* if it is not desirable.
*
* RETURN VALUE:
* The number of actually written scanlines returned or -1 if function fails.
****************************************************************************** */
int SaveAsTIFF(BITMAP *psBmp, char *pszFilename)
{
uint32 iWidth, iHeight;
float fXRes, fYRes;
uint16 iSPP, iBPP, iResUnit, iRowsPerStrip;
int iRow;
TIFF *fpOut;
BYTE *pbBuf;
if (psBmp->bmWidth <= 0 || psBmp->bmHeight <= 0 ||
(psBmp->bmBitsPixel != 1 && psBmp->bmBitsPixel != 8) ||
psBmp->bmPlanes < 1 || psBmp->bmBits == NULL)
{
fprintf (stderr, "Input image has wrong dimesions.\n");
return -1;
}
fpOut = TIFFOpen(pszFilename, "w");
if (!fpOut)
{
fprintf (stderr, "Can't open %s for writing.\n", pszFilename);
return -1;
}
iWidth = psBmp->bmWidth;
iHeight = psBmp->bmHeight;
iBPP = psBmp->bmBitsPixel;
if (psBmp->bmPlanes == 1)
iSPP = 1;
else
iSPP = 8;
TIFFSetField(fpOut, TIFFTAG_IMAGEWIDTH, iWidth);
TIFFSetField(fpOut, TIFFTAG_BITSPERSAMPLE, iBPP);
TIFFSetField(fpOut, TIFFTAG_SAMPLESPERPIXEL, iSPP);
TIFFSetField(fpOut, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(fpOut, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
TIFFSetField(fpOut, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
/* It is good to set resolutions too */
fXRes = fYRes = 100; /* dots per resolution unit (see below) */
iResUnit = RESUNIT_INCH; /* or RESUNIT_CENTIMETER */
TIFFSetField(fpOut, TIFFTAG_XRESOLUTION, fXRes);
TIFFSetField(fpOut, TIFFTAG_YRESOLUTION, fYRes);
TIFFSetField(fpOut, TIFFTAG_RESOLUTIONUNIT, iResUnit);
/* Uncomment the next line if you need compression.
* Possible options are:
*
* COMPRESSION_CCITTRLE CCITT modified Huffman RLE
* COMPRESSION_CCITTFAX3 CCITT Group 3 fax encoding
* COMPRESSION_CCITTFAX4 CCITT Group 4 fax encoding
* COMPRESSION_PACKBITS Macintosh RLE
*
* You may try all of these with your data to choose
* which one produces best results.
*/
/* TIFFSetField(fpOut, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4); */
iRowsPerStrip = TIFFDefaultStripSize(fpOut, 0);
TIFFSetField(fpOut,TIFFTAG_ROWSPERSTRIP, iRowsPerStrip);
pbBuf = (BYTE *)psBmp->bmBits;
for (iRow = 0; iRow < iHeight; iRow++)
{
if (TIFFWriteScanline(fpOut, pbBuf, iRow, 0) < 0)
{
fprintf(stderr, "Can't write scanline %d to file %s.\n",
iRow, pszFilename);
break;
}
pbBuf += psBmp->bmWidthBytes;
}
TIFFClose(fpOut);
return iRow; /* Number of successfuly written scanlines */
}
/* Below is the testsuite for the SavaAsTIFF() function */
BYTE bTest[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
BITMAP sTest[]=
{
{
0, 64, 18, 8, 1, 1, &bTest
},
{
0, 8, 18, 8, 1, 8, &bTest
},
{
0, 0, 0, 0, 0, 0, NULL
}
};
int main()
{
int i;
char szName[1024];
i = 0;
while (sTest[i].bmBits)
{
sprintf(szName, "out%d.tif", i);
if (SaveAsTIFF(&sTest[i], szName) < 0)
fprintf(stderr, "Test %d failed!\n", i);
else
fprintf(stderr, "Test %d succeeded!\n", i);
i++;
}
return 0;
}