bmpf.cpp
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:26k
源码类别:

打印编程

开发平台:

Visual C++

  1. /*
  2.    Copyright (C) 2007    Ibadov Tariel   <itk@bk.ru>
  3. */
  4. #include <fstream.h>
  5. #include "bmpf.h"
  6. #include "tchar.h"
  7. static unsigned char bmpHeader[62]; 
  8. static unsigned char bmpHeader1[62] =
  9. {        'B',  'M', 0xBE, 0x48, 0x28, 0x00, 0x00, 0x00,
  10.         0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x28, 0x00,
  11.         0x00, 0x00, 0xA4, 0x01, 0x00, 0x00, 0x9D, 0x00,
  12.         0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
  13.         0x00, 0x00, 0xBC, 0x04, 0x03, 0x00, 0x00, 0x00,
  14.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  15.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  16.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  17. };
  18. static unsigned char bmpHeader2[62] =
  19. {        'B',  'M', 0x3E, 0xF9, 0x15, 0x00, 0x00, 0x00,
  20.         0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x28, 0x00,
  21.         0x00, 0x00, 0xA4, 0x01, 0x00, 0x00, 0x9D, 0x00,
  22.         0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
  23.         0x00, 0x00, 0xBC, 0x04, 0x03, 0x00, 0x00, 0x00,
  24.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  25.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  26.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  27. };
  28. //==========================================================================================
  29. //PDF
  30. //==========================================================================================
  31. static unsigned char pdfHeader[9] =
  32. {        '%',  'P', 'D', 'F', '-', '1', '.', '2',0x0a};
  33. int pdf_save( char *filename, BMPINFO *pbmpinfo )
  34. {
  35. std::string  namepdf; 
  36. namepdf=filename;
  37. namepdf +=".pdf";
  38.     ofstream ofPdf;
  39.     ofPdf.open((const char *)namepdf.c_str(), ios::out | ios::binary );
  40. //-----------
  41. ofPdf.write((const char *) pdfHeader, 9 );
  42. ofPdf.write("1 0 objn", 8 );
  43. ofPdf.write("<<n", 3 );
  44. ofPdf.write("/Type /Catalogn", 15 );
  45. ofPdf.write("/Pages 2 0 Rn", 13 );
  46. ofPdf.write("/OpenAction [3 0 R /XYZ -32768 -32768 1 ]n", 42 );
  47.     ofPdf.write(">>n", 3 );
  48. ofPdf.write("endobjn", 7 );
  49. ofPdf.write("2 0 objn", 8 );
  50. ofPdf.write("<<n", 3 );
  51. ofPdf.write("/Type /Pagesn", 13 );
  52. ofPdf.write("/Kids [ 3 0 R ]n", 16 );
  53. ofPdf.write("/Count 1n", 9 );
  54.     ofPdf.write(">>n", 3 );
  55. ofPdf.write("endobjn", 7 ); 
  56. ofPdf.write("3 0 objn", 8 );
  57. ofPdf.write("<<n", 3 );
  58. ofPdf.write("/Type /Pagen", 12 );
  59. ofPdf.write("/Parent 2 0 Rn", 14 );
  60. ofPdf.write("/Resourcesn", 11 );
  61.     ofPdf.write("<<n", 3 );
  62. ofPdf.write("/XObject << /Im0 4 0 R >>n", 26 );
  63. ofPdf.write("/ProcSet [ /PDF /ImageC ]n", 26 );
  64.     ofPdf.write(">>n", 3 );
  65. if (pbmpinfo->height==600)
  66. ofPdf.write("/MediaBox [ 0 0 800 600 ]n", 26 );
  67. else
  68. ofPdf.write("/MediaBox [ 0 0 800 1100 ]n", 27 );
  69. ofPdf.write("/Contents 5 0 Rn", 16 );
  70. ofPdf.write(">>n", 3 );
  71. ofPdf.write("endobjn", 7 ); 
  72. ofPdf.write("4 0 objn", 8 );
  73. ofPdf.write("<<n", 3 );
  74. ofPdf.write("/Type /XObjectn", 15 );
  75. ofPdf.write("/Subtype /Imagen", 16 );
  76. ofPdf.write("/Name /Im0n", 11 );
  77.     ofPdf.write("/Width 800n", 11 );
  78. if (pbmpinfo->height==600)
  79. ofPdf.write("/Height 600n", 12 );
  80. else
  81. ofPdf.write("/Height 1100n", 13 );
  82.     ofPdf.write("/BitsPerComponent 8n", 20 );
  83. ofPdf.write("/Filter []n", 11 );
  84. ofPdf.write("/ColorSpace /DeviceRGBn", 23 );
  85. if (pbmpinfo->height==600)
  86. ofPdf.write("/Length 1440000 >>n", 19 );
  87. else
  88. ofPdf.write("/Length 2640000 >>n", 19 );
  89. ofPdf.write("streamn", 7 );
  90. ///==============================================================
  91. ///==============================================================
  92. unsigned long w = pbmpinfo->width;
  93.         unsigned long h = pbmpinfo->height;
  94. int bpl2 = w * 3;
  95. //unsigned char *p = pbmpinfo->bits + (bpl2 * h);
  96. unsigned char *p = pbmpinfo->bits;
  97.         for( unsigned y = 0; y < h; y++ ) {
  98. p += bpl2;
  99. ofPdf.write( (const char *)p, bpl2 );
  100. }
  101. ///==============================================================
  102. ///==============================================================
  103.     
  104. ofPdf.write("endstreamn", 10 );
  105. ofPdf.write("endobjn", 7 );
  106. ofPdf.write("5 0 objn", 8 );
  107. ofPdf.write("<< /Length 32 >>n", 17 );
  108. ofPdf.write("streamn", 7 );
  109. ofPdf.write("qn", 2 );
  110. if (pbmpinfo->height==600)
  111. ofPdf.write("800 0 0 600 0 0 cmn", 19 );
  112. else
  113. ofPdf.write("800 0 0 1100 0 0 cmn", 20 );
  114. ofPdf.write("/Im0 Don", 8 );
  115. ofPdf.write("Qn", 2 );
  116.     
  117. ofPdf.write("endstreamn", 10 );
  118. ofPdf.write("endobjn", 7 );
  119.     ofPdf.write("xrefn", 5 );
  120. ofPdf.write("0 6n", 4 );
  121. ofPdf.write("0000000000 65535 fn", 19 );
  122. ofPdf.write("0000000009 00000 nn", 19 );
  123. ofPdf.write("0000000100 00000 nn", 19 );
  124. ofPdf.write("0000000159 00000 nn", 19 );
  125. ofPdf.write("0000000318 00000 nn", 19 );
  126. ofPdf.write("0002640492 00000 nn", 19 );     
  127. ofPdf.write("trailern", 8 );
  128. ofPdf.write("<<n", 3 );
  129. ofPdf.write("/Size 6n", 8 );
  130. ofPdf.write("/Root 1 0 Rn", 12 );
  131. ofPdf.write(">>n", 3 );
  132. ofPdf.write("startxrefn", 10 );
  133. ofPdf.write("2640573n", 8 );
  134. ofPdf.write("%%EOF", 5 );
  135. //-----------
  136. ofPdf.close();
  137.     return 0;
  138. }
  139. int bmp_save( char *filename, BMPINFO *pbmpinfo )
  140. {
  141.         if (pbmpinfo->height==600){
  142.              for(int i=0;i<62;i++)                       
  143.                 bmpHeader[i]=bmpHeader2[i];
  144.         }else {
  145.                for(int i=0;i<62;i++)                       
  146.                 bmpHeader[i]=bmpHeader1[i];
  147.         }       
  148.         int endy = pbmpinfo->height - 1;
  149. int bpl = pbmpinfo->width*3; 
  150.         ofstream ofBmp;
  151.         ofBmp.open( filename, ios::out | ios::binary );
  152.         
  153. unsigned long w = pbmpinfo->width;
  154.         unsigned long h = endy + 1;
  155.         
  156. ofBmp.write((const char *) bmpHeader, 18 );
  157.         
  158. ofBmp.put( char( w      & 0x000000FF) );
  159. ofBmp.put( char((w>> 8) & 0x000000FF) );
  160.         ofBmp.put( char((w>>16) & 0x000000FF) );
  161.         ofBmp.put( char((w>>24) & 0x000000FF) );
  162.         ofBmp.put( char( h      & 0x000000FF) );
  163.         ofBmp.put( char((h>> 8) & 0x000000FF) );
  164.         ofBmp.put( char((h>>16) & 0x000000FF) );
  165.         ofBmp.put( char((h>>24) & 0x000000FF) );
  166.         ofBmp.write((const char *) bmpHeader + 26, sizeof(bmpHeader) - 26 );
  167. unsigned char *p = pbmpinfo->bits + bpl * h;
  168. int bpl2 = w * 3;
  169.         for( unsigned y = 0; y < h; y++ ) {
  170. p -= bpl;
  171. ofBmp.write( (const char *)p, bpl2 );
  172. }
  173.         ofBmp.close();
  174.         return 0;
  175. }
  176. //================================================================
  177. //                          TIFF                                                                                                    
  178. //================================================================
  179. enum BMPType
  180. {
  181.     BMPT_WIN4,      /* BMP used in Windows 3.0/NT 3.51/95 */
  182.     BMPT_WIN5,      /* BMP used in Windows NT 4.0/98/Me/2000/XP */
  183.     BMPT_OS21,      /* BMP used in OS/2 PM 1.x */
  184.     BMPT_OS22       /* BMP used in OS/2 PM 2.x */
  185. };
  186. enum BMPComprMethod
  187. {
  188.     BMPC_RGB = 0L,          /* Uncompressed */
  189.     BMPC_RLE8 = 1L,         /* RLE for 8 bpp images */
  190.     BMPC_RLE4 = 2L,         /* RLE for 4 bpp images */
  191.     BMPC_BITFIELDS = 3L,    /* Bitmap is not compressed and the colour table
  192.      * consists of three DWORD color masks that specify
  193.      * the red, green, and blue components of each
  194.      * pixel. This is valid when used with
  195.      * 16- and 32-bpp bitmaps. */
  196.     BMPC_JPEG = 4L,         /* Indicates that the image is a JPEG image. */
  197.     BMPC_PNG = 5L           /* Indicates that the image is a PNG image. */
  198. };
  199. enum BMPLCSType                 /* Type of logical color space. */
  200. {
  201.     BMPLT_CALIBRATED_RGB = 0, /* This value indicates that endpoints and
  202.  * gamma values are given in the appropriate
  203.  * fields. */
  204.     BMPLT_DEVICE_RGB = 1,
  205.     BMPLT_DEVICE_CMYK = 2
  206. };
  207. typedef struct
  208. {
  209.     int32   iCIEX;
  210.     int32   iCIEY;
  211.     int32   iCIEZ;
  212. } BMPCIEXYZ;
  213. typedef struct                  /* This structure contains the x, y, and z */
  214. { /* coordinates of the three colors that */
  215. /* correspond */
  216.     BMPCIEXYZ   iCIERed;        /* to the red, green, and blue endpoints for */
  217.     BMPCIEXYZ   iCIEGreen;      /* a specified logical color space. */
  218.     BMPCIEXYZ iCIEBlue;
  219. } BMPCIEXYZTriple;
  220. typedef struct
  221. {
  222.     char bType[2];       /* Signature "BM" */
  223.     uint32 iSize;          /* Size in bytes of the bitmap file. Should
  224.  * always be ignored while reading because
  225.  * of error in Windows 3.0 SDK's description
  226.  * of this field */
  227.     uint16 iReserved1;     /* Reserved, set as 0 */
  228.     uint16 iReserved2;     /* Reserved, set as 0 */
  229.     uint32 iOffBits;       /* Offset of the image from file start in bytes */
  230. } BMPFileHeader;
  231. /* File header size in bytes: */
  232. const int       BFH_SIZE = 14;
  233. typedef struct
  234. {
  235.     uint32 iSize;          /* Size of BMPInfoHeader structure in bytes.
  236.  * Should be used to determine start of the
  237.  * colour table */
  238.     int32 iWidth;         /* Image width */
  239.     int32 iHeight;        /* Image height. If positive, image has bottom
  240.  * left origin, if negative --- top left. */
  241.     int16 iPlanes;        /* Number of image planes (must be set to 1) */
  242.     int16 iBitCount;      /* Number of bits per pixel (1, 4, 8, 16, 24
  243.  * or 32). If 0 then the number of bits per
  244.  * pixel is specified or is implied by the
  245.  * JPEG or PNG format. */
  246.     uint32 iCompression; /* Compression method */
  247.     uint32 iSizeImage;     /* Size of uncomressed image in bytes. May
  248.  * be 0 for BMPC_RGB bitmaps. If iCompression
  249.  * is BI_JPEG or BI_PNG, iSizeImage indicates
  250.  * the size of the JPEG or PNG image buffer. */
  251.     int32 iXPelsPerMeter; /* X resolution, pixels per meter (0 if not used) */
  252.     int32 iYPelsPerMeter; /* Y resolution, pixels per meter (0 if not used) */
  253.     uint32 iClrUsed;       /* Size of colour table. If 0, iBitCount should
  254.  * be used to calculate this value
  255.  * (1<<iBitCount). This value should be
  256.  * unsigned for proper shifting. */
  257.     int32 iClrImportant;  /* Number of important colours. If 0, all
  258.  * colours are required */
  259.     /*
  260.      * Fields above should be used for bitmaps, compatible with Windows NT 3.51
  261.      * and earlier. Windows 98/Me, Windows 2000/XP introduces additional fields:
  262.      */
  263.     int32 iRedMask;       /* Colour mask that specifies the red component
  264.  * of each pixel, valid only if iCompression
  265.  * is set to BI_BITFIELDS. */
  266.     int32 iGreenMask;     /* The same for green component */
  267.     int32 iBlueMask;      /* The same for blue component */
  268.     int32 iAlphaMask;     /* Colour mask that specifies the alpha
  269.  * component of each pixel. */
  270.     uint32 iCSType;        /* Colour space of the DIB. */
  271.     BMPCIEXYZTriple sEndpoints; /* This member is ignored unless the iCSType
  272.  * member specifies BMPLT_CALIBRATED_RGB. */
  273.     int32 iGammaRed;      /* Toned response curve for red. This member
  274.  * is ignored unless color values are
  275.  * calibrated RGB values and iCSType is set to
  276.  * BMPLT_CALIBRATED_RGB. Specified
  277.  * in 16^16 format. */
  278.     int32 iGammaGreen;    /* Toned response curve for green. */
  279.     int32 iGammaBlue;     /* Toned response curve for blue. */
  280. } BMPInfoHeader;
  281. /*
  282.  * Info header size in bytes:
  283.  */
  284. const unsigned int  BIH_WIN4SIZE = 40; /* for BMPT_WIN4 */
  285. const unsigned int  BIH_WIN5SIZE = 57; /* for BMPT_WIN5 */
  286. const unsigned int  BIH_OS21SIZE = 12; /* for BMPT_OS21 */
  287. const unsigned int  BIH_OS22SIZE = 64; /* for BMPT_OS22 */
  288. /*
  289.  * We will use plain byte array instead of this structure, but declaration
  290.  * provided for reference
  291.  */
  292. typedef struct
  293. {
  294.     char       bBlue;
  295.     char       bGreen;
  296.     char       bRed;
  297.     char       bReserved;      /* Must be 0 */
  298. } BMPColorEntry;
  299. static uint16 compression = (uint16) -1;
  300. static int jpegcolormode = JPEGCOLORMODE_RGB;
  301. static int quality = 75; /* JPEG quality */
  302. static uint16 predictor = 0;
  303. static void usage(void);
  304. static int processCompressOptions(char*);
  305. static void rearrangePixels(char *, uint32, uint32);
  306. int start_toTiff(char *NameBmp, char *NameTiff, uint16 _compression)
  307. {
  308.     std::string  nametiff; 
  309. nametiff=NameBmp;
  310. nametiff +=".tif";
  311. uint32 width, length;
  312. uint16 nbands = 1; /* number of bands in input image */
  313.     uint16 depth = 8; /* bits per pixel in input image */
  314. uint32 rowsperstrip = (uint32) -1;
  315.     uint16 photometric = PHOTOMETRIC_MINISBLACK;
  316. int fd;
  317. struct stat instat;
  318. char *outfilename = NULL, *infilename = NULL;
  319. TIFF *out = NULL;
  320. BMPFileHeader file_hdr;
  321.         BMPInfoHeader info_hdr;
  322.         int     bmp_type;
  323.         uint32  clr_tbl_size, n_clr_elems = 3;
  324.         unsigned char *clr_tbl;
  325. unsigned short *red_tbl = NULL, *green_tbl = NULL, *blue_tbl = NULL;
  326. uint32 row, clr;
  327. int c;
  328. extern int optind;
  329. extern char* optarg;
  330. predictor =2;
  331.     compression = _compression;
  332. infilename =NameBmp;
  333. fd = open(infilename, O_RDONLY|O_BINARY, 0);
  334. if (fd < 0) {
  335. return -1;
  336. }
  337. read(fd, file_hdr.bType, 2);
  338. if(file_hdr.bType[0] != 'B' || file_hdr.bType[1] != 'M') {
  339. goto bad;
  340. }
  341. /* -------------------------------------------------------------------- */
  342. /*      Read the BMPFileHeader. We need iOffBits value only             */
  343. /* -------------------------------------------------------------------- */
  344. lseek(fd, 10, SEEK_SET);
  345. read(fd, &file_hdr.iOffBits, 4);
  346. fstat(fd, &instat);
  347. file_hdr.iSize = instat.st_size;
  348. /* -------------------------------------------------------------------- */
  349. /*      Read the BMPInfoHeader.                                         */
  350. /* -------------------------------------------------------------------- */
  351.         lseek(fd, BFH_SIZE, SEEK_SET);
  352.         read(fd, &info_hdr.iSize, 4);
  353.         if (info_hdr.iSize == BIH_WIN4SIZE)
  354.                 bmp_type = BMPT_WIN4;
  355.         else if (info_hdr.iSize == BIH_OS21SIZE)
  356.                 bmp_type = BMPT_OS21;
  357.         else if (info_hdr.iSize == BIH_OS22SIZE || info_hdr.iSize == 16)
  358.                 bmp_type = BMPT_OS22;
  359.         else
  360.                 bmp_type = BMPT_WIN5;
  361.         if (bmp_type == BMPT_WIN4 || bmp_type == BMPT_WIN5 || bmp_type == BMPT_OS22) {
  362.                 read(fd, &info_hdr.iWidth, 4);
  363.                 read(fd, &info_hdr.iHeight, 4);
  364.                 read(fd, &info_hdr.iPlanes, 2);
  365.                 read(fd, &info_hdr.iBitCount, 2);
  366.                 read(fd, &info_hdr.iCompression, 4);
  367.                 read(fd, &info_hdr.iSizeImage, 4);
  368.                 read(fd, &info_hdr.iXPelsPerMeter, 4);
  369.                 read(fd, &info_hdr.iYPelsPerMeter, 4);
  370.                 read(fd, &info_hdr.iClrUsed, 4);
  371.                 read(fd, &info_hdr.iClrImportant, 4);
  372.                 n_clr_elems = 4;
  373.         }
  374.         if (info_hdr.iBitCount != 1  && info_hdr.iBitCount != 4  &&
  375.             info_hdr.iBitCount != 8  && info_hdr.iBitCount != 16 &&
  376.             info_hdr.iBitCount != 24 && info_hdr.iBitCount != 32) {
  377.             close(fd);
  378.             return 0;
  379.         }
  380.         width = info_hdr.iWidth;
  381.         length = (info_hdr.iHeight > 0) ? info_hdr.iHeight : -info_hdr.iHeight;
  382. switch (info_hdr.iBitCount)
  383.         {
  384.                 case 1:
  385.                 case 4:
  386.                 case 8:
  387.                         nbands = 1;
  388. depth = info_hdr.iBitCount;
  389.                         photometric = PHOTOMETRIC_PALETTE;
  390.                         /* Allocate memory for colour table and read it. */
  391.                         if (info_hdr.iClrUsed)
  392.                             clr_tbl_size = ((uint32)(1 << depth) < info_hdr.iClrUsed) ?
  393.     (uint32) (1 << depth) : info_hdr.iClrUsed;
  394.                         else
  395.                             clr_tbl_size = 1 << depth;
  396.                         clr_tbl = (unsigned char *)
  397. _TIFFmalloc(n_clr_elems * clr_tbl_size);
  398. if (!clr_tbl) {
  399. goto bad;
  400. }
  401. lseek(fd, BFH_SIZE + info_hdr.iSize, SEEK_SET);
  402.                         read(fd, clr_tbl, n_clr_elems * clr_tbl_size);
  403. red_tbl = (unsigned short*)
  404. _TIFFmalloc(1<<depth * sizeof(unsigned short));
  405. if (!red_tbl) {
  406. goto bad1;
  407. }
  408. green_tbl = (unsigned short*)
  409. _TIFFmalloc(1<<depth * sizeof(unsigned short));
  410. if (!green_tbl) {
  411. goto bad2;
  412. }
  413. blue_tbl = (unsigned short*)
  414. _TIFFmalloc(1<<depth * sizeof(unsigned short));
  415. if (!blue_tbl) {
  416. goto bad3;
  417. }
  418.                         for(clr = 0; clr < clr_tbl_size; clr++) {
  419.                             red_tbl[clr] = 257 * clr_tbl[clr*n_clr_elems+2];
  420.                             green_tbl[clr] = 257 * clr_tbl[clr*n_clr_elems+1];
  421.                             blue_tbl[clr] = 257 * clr_tbl[clr*n_clr_elems];
  422.                         }
  423.                         _TIFFfree(clr_tbl);
  424.                         break;
  425.                 case 16:
  426.                 case 24:
  427.                         nbands = 3;
  428. depth = info_hdr.iBitCount / nbands;
  429.                         photometric = PHOTOMETRIC_RGB;
  430.                         break;
  431.                 case 32:
  432.                         nbands = 3;
  433. depth = 8;
  434.                         photometric = PHOTOMETRIC_RGB;
  435.                         break;
  436.                 default:
  437.                         break;
  438.         }
  439. /* -------------------------------------------------------------------- */
  440. /*  Create output file.                                                 */
  441. /* -------------------------------------------------------------------- */
  442. if (outfilename == NULL)
  443. outfilename =  (char *)nametiff.c_str();
  444. out = TIFFOpen(outfilename, "w");
  445. if (out == NULL) {
  446. goto bad3;
  447. }
  448. TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
  449. TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
  450. TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, nbands);
  451. TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, depth);
  452. TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  453.     switch( compression )
  454.     {
  455.     case COMPRESSION_CCITTFAX3:
  456.          {
  457.   TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  458.           TIFFSetField(out, TIFFTAG_SUBFILETYPE, 0); 
  459.           TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);          
  460.           TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, rowsperstrip));
  461.           TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
  462.   TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING|GROUP3OPT_FILLBITS);
  463.   TIFFSetField(out, TIFFTAG_FAXMODE, FAXMODE_CLASSIC/* generate "classic" g3 format */);
  464.           TIFFSetField( out, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB);
  465.           TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
  466.           TIFFSetField(out, TIFFTAG_XRESOLUTION, 204.0);
  467.           TIFFSetField(out, TIFFTAG_YRESOLUTION, 196.0);          
  468.          }break;
  469.     case COMPRESSION_CCITTFAX4:
  470.          {
  471. TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  472.           TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
  473.           TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, rowsperstrip));
  474.       TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
  475.           TIFFSetField(out, TIFFTAG_SUBFILETYPE, 0);
  476.       TIFFSetField(out, TIFFTAG_GROUP4OPTIONS, 0);
  477.       TIFFSetField(out, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
  478.       TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
  479.           TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
  480.           TIFFSetField(out, TIFFTAG_XRESOLUTION, 1.0);
  481.           TIFFSetField(out, TIFFTAG_YRESOLUTION, 1.0);
  482.           break;
  483.           }
  484.     default:
  485.     {
  486. TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  487. TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
  488.         TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, rowsperstrip));
  489.         if (red_tbl && green_tbl && blue_tbl)
  490.    TIFFSetField(out, TIFFTAG_COLORMAP, red_tbl, green_tbl, blue_tbl);
  491.        if (compression == (uint16) -1)
  492.    compression = COMPRESSION_PACKBITS;
  493.     TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
  494.     switch (compression) {
  495.         case COMPRESSION_JPEG:
  496. if (photometric == PHOTOMETRIC_RGB
  497.     && jpegcolormode == JPEGCOLORMODE_RGB)
  498. photometric = PHOTOMETRIC_YCBCR;
  499. TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
  500. TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
  501. break;
  502.     case COMPRESSION_LZW:
  503.         case COMPRESSION_DEFLATE:
  504. if (predictor != 0)
  505. TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
  506. break;
  507. }
  508.     }
  509.     }
  510. /* -------------------------------------------------------------------- */
  511. /*  Read uncompressed image data.                                       */
  512. /* -------------------------------------------------------------------- */
  513.         if (info_hdr.iCompression == BMPC_RGB) {
  514.                 uint32 offset, size;
  515.                 char *scanbuf;
  516. /* XXX: Avoid integer overflow. We can calculate size in one
  517.  * step using
  518.  *
  519.  *   size = ((width * info_hdr.iBitCount + 31) & ~31) / 8
  520.  *
  521.  * formulae, but we should check for overflow conditions
  522.  * during calculation.
  523.  */
  524. size = width * info_hdr.iBitCount + 31;
  525. if (!width || !info_hdr.iBitCount
  526.     || (size - 31) / info_hdr.iBitCount != width ) {
  527. goto bad3;
  528. }
  529.                 size = (size & ~31) / 8;
  530.                 scanbuf = (char *) _TIFFmalloc(size);
  531. if (!scanbuf) {
  532. goto bad3;
  533. }
  534.                 for (row = 0; row < length; row++) {
  535.                         if (info_hdr.iHeight > 0)
  536.                                 offset = file_hdr.iOffBits + (length - row - 1) * size;
  537.                         else
  538.                                 offset = file_hdr.iOffBits + row * size;
  539.                         if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
  540. break;
  541.                         }
  542. if (read(fd, scanbuf, size) < 0) {
  543. break;
  544.                         }
  545.                         rearrangePixels(scanbuf, width, info_hdr.iBitCount);
  546.                         if (TIFFWriteScanline(out, scanbuf, row, 0) < 0) {
  547. break;
  548.                         }
  549.                 }
  550.                 _TIFFfree(scanbuf);
  551. /* -------------------------------------------------------------------- */
  552. /*  Read compressed image data.                                         */
  553. /* -------------------------------------------------------------------- */
  554.         } else if ( info_hdr.iCompression == BMPC_RLE8
  555.     || info_hdr.iCompression == BMPC_RLE4 ) {
  556. uint32 i, j, k, runlength;
  557. uint32 compr_size, uncompr_size;
  558. unsigned char   *comprbuf;
  559. unsigned char   *uncomprbuf;
  560. compr_size = file_hdr.iSize - file_hdr.iOffBits;
  561. uncompr_size = width * length;
  562. comprbuf = (unsigned char *) _TIFFmalloc( compr_size );
  563. if (!comprbuf) {
  564. goto bad3;
  565. }
  566. uncomprbuf = (unsigned char *) _TIFFmalloc( uncompr_size );
  567. if (!uncomprbuf) {
  568. goto bad3;
  569. }
  570. lseek(fd, file_hdr.iOffBits, SEEK_SET);
  571. read(fd, comprbuf, compr_size);
  572. i = 0;
  573. j = 0;
  574. if (info_hdr.iBitCount == 8) {     /* RLE8 */
  575.     while( j < uncompr_size && i < compr_size ) {
  576. if ( comprbuf[i] ) {
  577.     runlength = comprbuf[i++];
  578.     while( runlength > 0
  579.    && j < uncompr_size
  580.    && i < compr_size ) {
  581. uncomprbuf[j++] = comprbuf[i];
  582. runlength--;
  583.     }
  584.     i++;
  585. } else {
  586.     i++;
  587.     if ( comprbuf[i] == 0 )         /* Next scanline */
  588. i++;
  589.     else if ( comprbuf[i] == 1 )    /* End of image */
  590. break;
  591.     else if ( comprbuf[i] == 2 ) {  /* Move to... */
  592. i++;
  593. if ( i < compr_size - 1 ) {
  594.     j += comprbuf[i] + comprbuf[i+1] * width;
  595.     i += 2;
  596. }
  597. else
  598.     break;
  599.     } else {                         /* Absolute mode */
  600. runlength = comprbuf[i++];
  601. for ( k = 0; k < runlength && j < uncompr_size && i < compr_size; k++ )
  602.     uncomprbuf[j++] = comprbuf[i++];
  603. if ( k & 0x01 )
  604.     i++;
  605.     }
  606. }
  607.     }
  608. }
  609. else {     /* RLE4 */
  610.     while( j < uncompr_size && i < compr_size ) {
  611. if ( comprbuf[i] ) {
  612.     runlength = comprbuf[i++];
  613.     while( runlength > 0 && j < uncompr_size && i < compr_size ) {
  614. if ( runlength & 0x01 )
  615.     uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4;
  616. else
  617.     uncomprbuf[j++] = comprbuf[i] & 0x0F;
  618. runlength--;
  619.     }
  620.     i++;
  621. } else {
  622.     i++;
  623.     if ( comprbuf[i] == 0 )         /* Next scanline */
  624. i++;
  625.     else if ( comprbuf[i] == 1 )    /* End of image */
  626. break;
  627.     else if ( comprbuf[i] == 2 ) {  /* Move to... */
  628. i++;
  629. if ( i < compr_size - 1 ) {
  630.     j += comprbuf[i] + comprbuf[i+1] * width;
  631.     i += 2;
  632. }
  633. else
  634.     break;
  635.     } else {                        /* Absolute mode */
  636. runlength = comprbuf[i++];
  637. for ( k = 0; k < runlength && j < uncompr_size && i < compr_size; k++) {
  638.     if ( k & 0x01 )
  639. uncomprbuf[j++] = comprbuf[i++] & 0x0F;
  640.     else
  641. uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4;
  642. }
  643. if ( k & 0x01 )
  644.     i++;
  645.     }
  646. }
  647.     }
  648. }
  649. _TIFFfree(comprbuf);
  650. for (row = 0; row < length; row++) {
  651.                         if (TIFFWriteScanline(out, uncomprbuf + (length - row - 1) * width, row, 0) < 0) 
  652.                         {}
  653. }
  654. _TIFFfree(uncomprbuf);
  655. }
  656. bad3:
  657. if (blue_tbl)
  658. _TIFFfree(blue_tbl);
  659. bad2:
  660. if (green_tbl)
  661. _TIFFfree(green_tbl);
  662. bad1:
  663. if (red_tbl)
  664. _TIFFfree(red_tbl);
  665. bad:
  666.         close(fd);
  667. if (out)
  668. TIFFClose(out);
  669.         return 0;
  670. }
  671. /*
  672.  * Image data in BMP file stored in BGR (or ABGR) format. We should rearrange
  673.  * pixels to RGB (RGBA) format.
  674.  */
  675. static void
  676. rearrangePixels(char *buf, uint32 width, uint32 bit_count)
  677. {
  678. char tmp;
  679. uint32 i;
  680.         switch(bit_count) {
  681. case 16:    /* FIXME: need a sample file */
  682.                         break;
  683.                 case 24:
  684. for (i = 0; i < width; i++, buf += 3) {
  685. tmp = *buf;
  686. *buf = *(buf + 2);
  687. *(buf + 2) = tmp;
  688. }
  689.                         break;
  690.                 case 32:
  691. {
  692. char *buf1 = buf;
  693. for (i = 0; i < width; i++, buf += 4) {
  694. tmp = *buf;
  695. *buf1++ = *(buf + 2);
  696. *buf1++ = *(buf + 1);
  697. *buf1++ = tmp;
  698. }
  699. }
  700.                         break;
  701.                 default:
  702.                         break;
  703.         }
  704. }