tiff2dib.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*************************************************************************
  2. *
  3. * Source file for Windows 95/Win32.
  4. *
  5. * The function LoadTIFFinDIB in this source file let you load
  6. * a TIFF file and build a memory DIB with it and return the
  7. * HANDLE (HDIB) of the memory bloc containing the DIB.
  8. *
  9. * Example :
  10. *
  11. * HDIB hDIB;
  12. * hDIB = LoadTIFFinDIB("sample.tif");
  13. *
  14. *
  15. * To build this source file you must include the TIFF library
  16. * in your project.
  17. *
  18. * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com
  19. *
  20. ************************************************************************/
  21. #include "tiffio.h"
  22. #define HDIB HANDLE
  23. #define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
  24. #define CVT(x) (((x) * 255L) / ((1L<<16)-1))
  25. static HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount);
  26. static LPSTR FindDIBBits(LPSTR lpDIB);
  27. static WORD PaletteSize(LPSTR lpDIB);
  28. static WORD DIBNumColors(LPSTR lpDIB);
  29. static int checkcmap(int n, uint16* r, uint16* g, uint16* b);
  30. /*************************************************************************
  31. *
  32. * HDIB LoadTIFFinDIB(LPSTR lpFileName)
  33. *
  34. * Parameter:
  35. *
  36. * LPSTR lpDIB - File name of a tiff imag
  37. *
  38. * Return Value:
  39. *
  40. * LPSTR - HANDLE of a DIB
  41. *
  42. * Description:
  43. *
  44. * This function load a TIFF file and build a memory DIB with it
  45. * and return the HANDLE (HDIB) of the memory bloc containing
  46. * the DIB.
  47. *
  48. * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com
  49. *
  50. ************************************************************************/
  51. HDIB LoadTIFFinDIB(LPSTR lpFileName)
  52. {
  53. TIFF *tif;
  54. unsigned long imageLength;
  55. unsigned long imageWidth;
  56. unsigned int BitsPerSample;
  57. unsigned long LineSize;
  58. unsigned int SamplePerPixel;
  59. unsigned long RowsPerStrip;
  60. int PhotometricInterpretation;
  61. long nrow;
  62. unsigned long row;
  63. char *buf;
  64. LPBITMAPINFOHEADER lpDIB;
  65. HDIB hDIB;
  66. char *lpBits;
  67. HGLOBAL hStrip;
  68. int i,l;
  69. int Align;
  70. tif = TIFFOpen(lpFileName, "r");
  71. if (!tif)
  72. goto TiffOpenError;
  73. TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
  74. TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
  75. TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
  76. TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
  77. TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
  78. TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
  79. LineSize = TIFFScanlineSize(tif); //Number of byte in ine line
  80. SamplePerPixel = (int) (LineSize/imageWidth);
  81. //Align = Number of byte to add at the end of each line of the DIB
  82. Align = 4 - (LineSize % 4);
  83. if (Align == 4) Align = 0;
  84. //Create a new DIB
  85. hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD)
  86. (BitsPerSample*SamplePerPixel));
  87. lpDIB = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
  88. if (!lpDIB)
  89. goto OutOfDIBMemory;
  90. if (lpDIB)
  91. lpBits = FindDIBBits((LPSTR) lpDIB);
  92. //In the tiff file the lines are save from up to down
  93. //In a DIB the lines must be save from down to up
  94. if (lpBits)
  95. {
  96. lpBits = FindDIBBits((LPSTR) lpDIB);
  97. lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1);
  98. //now lpBits pointe on the bottom line
  99. hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
  100. buf = GlobalLock(hStrip);
  101. if (!buf)
  102. goto OutOfBufMemory;
  103. //PhotometricInterpretation = 2 image is RGB
  104. //PhotometricInterpretation = 3 image have a color palette
  105. if (PhotometricInterpretation == 3)
  106. {
  107. uint16* red;
  108. uint16* green;
  109. uint16* blue;
  110. int16 i;
  111. LPBITMAPINFO lpbmi;
  112. int Palette16Bits;
  113. TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
  114. //Is the palette 16 or 8 bits ?
  115. if (checkcmap(1<<BitsPerSample, red, green, blue) == 16)
  116. Palette16Bits = TRUE;
  117. else
  118. Palette16Bits = FALSE;
  119. lpbmi = (LPBITMAPINFO)lpDIB;
  120. //load the palette in the DIB
  121. for (i = (1<<BitsPerSample)-1; i >= 0; i--)
  122. {
  123. if (Palette16Bits)
  124. {
  125. lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]);
  126. lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]);
  127. lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]);
  128. }
  129. else
  130. {
  131. lpbmi->bmiColors[i].rgbRed = (BYTE) red[i];
  132. lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i];
  133. lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i];
  134. }
  135. }
  136. }
  137. //read the tiff lines and save them in the DIB
  138. //with RGB mode, we have to change the order of the 3 samples RGB
  139. <=> BGR
  140. for (row = 0; row < imageLength; row += RowsPerStrip)
  141. {
  142. nrow = (row + RowsPerStrip > imageLength ? imageLength - row :
  143. RowsPerStrip);
  144. if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  145. buf, nrow*LineSize)==-1)
  146. {
  147. goto TiffReadError;
  148. }
  149. else
  150. {
  151. for (l = 0; l < nrow; l++)
  152. {
  153. if (SamplePerPixel == 3)
  154. for (i=0;i< (int) (imageWidth);i++)
  155. {
  156. lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample
  157. PerPixel+2];
  158. lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample
  159. PerPixel+1];
  160. lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample
  161. PerPixel+0];
  162. }
  163. else
  164. memcpy(lpBits, &buf[(int) (l*LineSize)], (int)
  165. imageWidth*SamplePerPixel);
  166. lpBits-=imageWidth*SamplePerPixel+Align;
  167. }
  168. }
  169. }
  170. GlobalUnlock(hStrip);
  171. GlobalFree(hStrip);
  172. GlobalUnlock(hDIB);
  173. TIFFClose(tif);
  174. }
  175. return hDIB;
  176. OutOfBufMemory:
  177. TiffReadError:
  178. GlobalUnlock(hDIB);
  179. GlobalFree(hStrip);
  180. OutOfDIBMemory:
  181. TIFFClose(tif);
  182. TiffOpenError:
  183. return (HANDLE) 0;
  184. }
  185. static int checkcmap(int n, uint16* r, uint16* g, uint16* b)
  186. {
  187. while (n-- > 0)
  188. if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  189. return (16);
  190. return (8);
  191. }
  192. /*************************************************************************
  193. * All the following functions were created by microsoft, they are
  194. * parts of the sample project "wincap" given with the SDK Win32.
  195. *
  196. * Microsoft says that :
  197. *
  198. * You have a royalty-free right to use, modify, reproduce and
  199. * distribute the Sample Files (and/or any modified version) in
  200. * any way you find useful, provided that you agree that
  201. * Microsoft has no warranty obligations or liability for any
  202. * Sample Application Files which are modified.
  203. *
  204. ************************************************************************/
  205. HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
  206. {
  207. BITMAPINFOHEADER bi; // bitmap header
  208. LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER
  209. DWORD dwLen; // size of memory block
  210. HDIB hDIB;
  211. DWORD dwBytesPerLine; // Number of bytes per scanline
  212. // Make sure bits per pixel is valid
  213. if (wBitCount <= 1)
  214. wBitCount = 1;
  215. else if (wBitCount <= 4)
  216. wBitCount = 4;
  217. else if (wBitCount <= 8)
  218. wBitCount = 8;
  219. else if (wBitCount <= 24)
  220. wBitCount = 24;
  221. else
  222. wBitCount = 4; // set default value to 4 if parameter is bogus
  223. // initialize BITMAPINFOHEADER
  224. bi.biSize = sizeof(BITMAPINFOHEADER);
  225. bi.biWidth = dwWidth; // fill in width from parameter
  226. bi.biHeight = dwHeight; // fill in height from parameter
  227. bi.biPlanes = 1; // must be 1
  228. bi.biBitCount = wBitCount; // from parameter
  229. bi.biCompression = BI_RGB;
  230. bi.biSizeImage = (dwWidth*dwHeight*wBitCount)/8; //0; // 0's here
  231. mean "default"
  232. bi.biXPelsPerMeter = 2834; //0;
  233. bi.biYPelsPerMeter = 2834; //0;
  234. bi.biClrUsed = 0;
  235. bi.biClrImportant = 0;
  236. // calculate size of memory block required to store the DIB. This
  237. // block should be big enough to hold the BITMAPINFOHEADER, the color
  238. // table, and the bits
  239. dwBytesPerLine = (((wBitCount * dwWidth) + 31) / 32 * 4);
  240. dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight);
  241. // alloc memory block to store our bitmap
  242. hDIB = GlobalAlloc(GHND, dwLen);
  243. // major bummer if we couldn't get memory block
  244. if (!hDIB)
  245. {
  246. return NULL;
  247. }
  248. // lock memory and get pointer to it
  249. lpbi = (VOID FAR *)GlobalLock(hDIB);
  250. // use our bitmap info structure to fill in first part of
  251. // our DIB with the BITMAPINFOHEADER
  252. *lpbi = bi;
  253. // Since we don't know what the colortable and bits should contain,
  254. // just leave these blank. Unlock the DIB and return the HDIB.
  255. GlobalUnlock(hDIB);
  256. /* return handle to the DIB */
  257. return hDIB;
  258. }
  259. LPSTR FAR FindDIBBits(LPSTR lpDIB)
  260. {
  261. return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB));
  262. }
  263. WORD FAR PaletteSize(LPSTR lpDIB)
  264. {
  265. /* calculate the size required by the palette */
  266. if (IS_WIN30_DIB (lpDIB))
  267. return (DIBNumColors(lpDIB) * sizeof(RGBQUAD));
  268. else
  269. return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
  270. }
  271. WORD DIBNumColors(LPSTR lpDIB)
  272. {
  273. WORD wBitCount; // DIB bit count
  274. /* If this is a Windows-style DIB, the number of colors in the
  275. * color table can be less than the number of bits per pixel
  276. * allows for (i.e. lpbi->biClrUsed can be set to some value).
  277. * If this is the case, return the appropriate value.
  278. */
  279. if (IS_WIN30_DIB(lpDIB))
  280. {
  281. DWORD dwClrUsed;
  282. dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
  283. if (dwClrUsed)
  284. return (WORD)dwClrUsed;
  285. }
  286. /* Calculate the number of colors in the color table based on
  287. * the number of bits per pixel for the DIB.
  288. */
  289. if (IS_WIN30_DIB(lpDIB))
  290. wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
  291. else
  292. wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
  293. /* return number of colors based on bits per pixel */
  294. switch (wBitCount)
  295. {
  296. case 1:
  297. return 2;
  298. case 4:
  299. return 16;
  300. case 8:
  301. return 256;
  302. default:
  303. return 0;
  304. }
  305. }
  306. /*
  307. * Local Variables:
  308. * mode: c
  309. * c-basic-offset: 8
  310. * fill-column: 78
  311. * End:
  312. */