You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

496 lines
12KB

  1. //
  2. // "$Id: Fl_BMP_Image.cxx 7903 2010-11-28 21:06:39Z matt $"
  3. //
  4. // Fl_BMP_Image routines.
  5. //
  6. // Copyright 1997-2010 by Easy Software Products.
  7. // Image support by Matthias Melcher, Copyright 2000-2009.
  8. //
  9. // This library is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU Library General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. //
  14. // This library is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. // Library General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU Library General Public
  20. // License along with this library; if not, write to the Free Software
  21. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  22. // USA.
  23. //
  24. // Please report all bugs and problems on the following page:
  25. //
  26. // http://www.fltk.org/str.php
  27. //
  28. // Contents:
  29. //
  30. // Fl_BMP_Image::Fl_BMP_Image() - Load a BMP image file.
  31. //
  32. //
  33. // Include necessary header files...
  34. //
  35. #include <FL/Fl_BMP_Image.H>
  36. #include <FL/fl_utf8.h>
  37. #include <config.h>
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. //
  41. // BMP definitions...
  42. //
  43. #ifndef BI_RGB
  44. # define BI_RGB 0 // No compression - straight BGR data
  45. # define BI_RLE8 1 // 8-bit run-length compression
  46. # define BI_RLE4 2 // 4-bit run-length compression
  47. # define BI_BITFIELDS 3 // RGB bitmap with RGB masks
  48. #endif // !BI_RGB
  49. //
  50. // Local functions...
  51. //
  52. static int read_long(FILE *fp);
  53. static unsigned short read_word(FILE *fp);
  54. static unsigned int read_dword(FILE *fp);
  55. /**
  56. The constructor loads the named BMP image from the given bmp filename.
  57. <P>The inherited destructor free all memory and server resources that are used by
  58. the image.
  59. <P>The destructor free all memory and server resources that are used by
  60. the image
  61. */
  62. Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
  63. : Fl_RGB_Image(0,0,0) {
  64. FILE *fp; // File pointer
  65. int info_size, // Size of info header
  66. depth, // Depth of image (bits)
  67. bDepth = 3, // Depth of image (bytes)
  68. compression, // Type of compression
  69. colors_used, // Number of colors used
  70. x, y, // Looping vars
  71. color, // Color of RLE pixel
  72. repcount, // Number of times to repeat
  73. temp, // Temporary color
  74. align, // Alignment bytes
  75. dataSize, // number of bytes in image data set
  76. row_order, // 1 = normal; -1 = flipped row order
  77. start_y, // Beginning Y
  78. end_y; // Ending Y
  79. long offbits; // Offset to image data
  80. uchar bit, // Bit in image
  81. byte; // Byte in image
  82. uchar *ptr; // Pointer into pixels
  83. uchar colormap[256][3];// Colormap
  84. uchar havemask; // Single bit mask follows image data
  85. int use_5_6_5; // Use 5:6:5 for R:G:B channels in 16 bit images
  86. // Open the file...
  87. if ((fp = fl_fopen(bmp, "rb")) == NULL) return;
  88. // Get the header...
  89. byte = (uchar)getc(fp); // Check "BM" sync chars
  90. bit = (uchar)getc(fp);
  91. if (byte != 'B' || bit != 'M') {
  92. fclose(fp);
  93. return;
  94. }
  95. read_dword(fp); // Skip size
  96. read_word(fp); // Skip reserved stuff
  97. read_word(fp);
  98. offbits = (long)read_dword(fp);// Read offset to image data
  99. // Then the bitmap information...
  100. info_size = read_dword(fp);
  101. // printf("offbits = %ld, info_size = %d\n", offbits, info_size);
  102. havemask = 0;
  103. row_order = -1;
  104. use_5_6_5 = 0;
  105. if (info_size < 40) {
  106. // Old Windows/OS2 BMP header...
  107. w(read_word(fp));
  108. h(read_word(fp));
  109. read_word(fp);
  110. depth = read_word(fp);
  111. compression = BI_RGB;
  112. colors_used = 0;
  113. repcount = info_size - 12;
  114. } else {
  115. // New BMP header...
  116. w(read_long(fp));
  117. // If the height is negative, the row order is flipped
  118. temp = read_long(fp);
  119. if (temp < 0) row_order = 1;
  120. h(abs(temp));
  121. read_word(fp);
  122. depth = read_word(fp);
  123. compression = read_dword(fp);
  124. dataSize = read_dword(fp);
  125. read_long(fp);
  126. read_long(fp);
  127. colors_used = read_dword(fp);
  128. read_dword(fp);
  129. repcount = info_size - 40;
  130. if (!compression && depth>=8 && w()>32/depth) {
  131. int Bpp = depth/8;
  132. int maskSize = (((w()*Bpp+3)&~3)*h()) + (((((w()+7)/8)+3)&~3)*h());
  133. if (maskSize==2*dataSize) {
  134. havemask = 1;
  135. h(h()/2);
  136. bDepth = 4;
  137. }
  138. }
  139. }
  140. // printf("w() = %d, h() = %d, depth = %d, compression = %d, colors_used = %d, repcount = %d\n",
  141. // w(), h(), depth, compression, colors_used, repcount);
  142. // Skip remaining header bytes...
  143. while (repcount > 0) {
  144. getc(fp);
  145. repcount --;
  146. }
  147. // Check header data...
  148. if (!w() || !h() || !depth) {
  149. fclose(fp);
  150. return;
  151. }
  152. // Get colormap...
  153. if (colors_used == 0 && depth <= 8)
  154. colors_used = 1 << depth;
  155. for (repcount = 0; repcount < colors_used; repcount ++) {
  156. // Read BGR color...
  157. if (fread(colormap[repcount], 1, 3, fp)==0) { /* ignore */ }
  158. // Skip pad byte for new BMP files...
  159. if (info_size > 12) getc(fp);
  160. }
  161. // Read first dword of colormap. It tells us if 5:5:5 or 5:6:5 for 16 bit
  162. if (depth == 16)
  163. use_5_6_5 = (read_dword(fp) == 0xf800);
  164. // Set byte depth for RGBA images
  165. if (depth == 32)
  166. bDepth=4;
  167. // Setup image and buffers...
  168. d(bDepth);
  169. if (offbits) fseek(fp, offbits, SEEK_SET);
  170. array = new uchar[w() * h() * d()];
  171. alloc_array = 1;
  172. // Read the image data...
  173. color = 0;
  174. repcount = 0;
  175. align = 0;
  176. byte = 0;
  177. temp = 0;
  178. if (row_order < 0) {
  179. start_y = h() - 1;
  180. end_y = -1;
  181. } else {
  182. start_y = 0;
  183. end_y = h();
  184. }
  185. for (y = start_y; y != end_y; y += row_order) {
  186. ptr = (uchar *)array + y * w() * d();
  187. switch (depth)
  188. {
  189. case 1 : // Bitmap
  190. for (x = w(), bit = 128; x > 0; x --) {
  191. if (bit == 128) byte = (uchar)getc(fp);
  192. if (byte & bit) {
  193. *ptr++ = colormap[1][2];
  194. *ptr++ = colormap[1][1];
  195. *ptr++ = colormap[1][0];
  196. } else {
  197. *ptr++ = colormap[0][2];
  198. *ptr++ = colormap[0][1];
  199. *ptr++ = colormap[0][0];
  200. }
  201. if (bit > 1)
  202. bit >>= 1;
  203. else
  204. bit = 128;
  205. }
  206. // Read remaining bytes to align to 32 bits...
  207. for (temp = (w() + 7) / 8; temp & 3; temp ++) {
  208. getc(fp);
  209. }
  210. break;
  211. case 4 : // 16-color
  212. for (x = w(), bit = 0xf0; x > 0; x --) {
  213. // Get a new repcount as needed...
  214. if (repcount == 0) {
  215. if (compression != BI_RLE4) {
  216. repcount = 2;
  217. color = -1;
  218. } else {
  219. while (align > 0) {
  220. align --;
  221. getc(fp);
  222. }
  223. if ((repcount = getc(fp)) == 0) {
  224. if ((repcount = getc(fp)) == 0) {
  225. // End of line...
  226. x ++;
  227. continue;
  228. } else if (repcount == 1) {
  229. // End of image...
  230. break;
  231. } else if (repcount == 2) {
  232. // Delta...
  233. repcount = getc(fp) * getc(fp) * w();
  234. color = 0;
  235. } else {
  236. // Absolute...
  237. color = -1;
  238. align = ((4 - (repcount & 3)) / 2) & 1;
  239. }
  240. } else {
  241. color = getc(fp);
  242. }
  243. }
  244. }
  245. // Get a new color as needed...
  246. repcount --;
  247. // Extract the next pixel...
  248. if (bit == 0xf0) {
  249. // Get the next color byte as needed...
  250. if (color < 0) temp = getc(fp);
  251. else temp = color;
  252. // Copy the color value...
  253. *ptr++ = colormap[(temp >> 4) & 15][2];
  254. *ptr++ = colormap[(temp >> 4) & 15][1];
  255. *ptr++ = colormap[(temp >> 4) & 15][0];
  256. bit = 0x0f;
  257. } else {
  258. bit = 0xf0;
  259. // Copy the color value...
  260. *ptr++ = colormap[temp & 15][2];
  261. *ptr++ = colormap[temp & 15][1];
  262. *ptr++ = colormap[temp & 15][0];
  263. }
  264. }
  265. if (!compression) {
  266. // Read remaining bytes to align to 32 bits...
  267. for (temp = (w() + 1) / 2; temp & 3; temp ++) {
  268. getc(fp);
  269. }
  270. }
  271. break;
  272. case 8 : // 256-color
  273. for (x = w(); x > 0; x --) {
  274. // Get a new repcount as needed...
  275. if (compression != BI_RLE8) {
  276. repcount = 1;
  277. color = -1;
  278. }
  279. if (repcount == 0) {
  280. while (align > 0) {
  281. align --;
  282. getc(fp);
  283. }
  284. if ((repcount = getc(fp)) == 0) {
  285. if ((repcount = getc(fp)) == 0) {
  286. // End of line...
  287. x ++;
  288. continue;
  289. } else if (repcount == 1) {
  290. // End of image...
  291. break;
  292. } else if (repcount == 2) {
  293. // Delta...
  294. repcount = getc(fp) * getc(fp) * w();
  295. color = 0;
  296. } else {
  297. // Absolute...
  298. color = -1;
  299. align = (2 - (repcount & 1)) & 1;
  300. }
  301. } else {
  302. color = getc(fp);
  303. }
  304. }
  305. // Get a new color as needed...
  306. if (color < 0) temp = getc(fp);
  307. else temp = color;
  308. repcount --;
  309. // Copy the color value...
  310. *ptr++ = colormap[temp][2];
  311. *ptr++ = colormap[temp][1];
  312. *ptr++ = colormap[temp][0];
  313. if (havemask) ptr++;
  314. }
  315. if (!compression) {
  316. // Read remaining bytes to align to 32 bits...
  317. for (temp = w(); temp & 3; temp ++) {
  318. getc(fp);
  319. }
  320. }
  321. break;
  322. case 16 : // 16-bit 5:5:5 or 5:6:5 RGB
  323. for (x = w(); x > 0; x --, ptr += bDepth) {
  324. uchar b = getc(fp), a = getc(fp) ;
  325. if (use_5_6_5) {
  326. ptr[2] = (uchar)(( b << 3 ) & 0xf8);
  327. ptr[1] = (uchar)(((a << 5) & 0xe0) | ((b >> 3) & 0x1c));
  328. ptr[0] = (uchar)(a & 0xf8);
  329. } else {
  330. ptr[2] = (uchar)((b << 3) & 0xf8);
  331. ptr[1] = (uchar)(((a << 6) & 0xc0) | ((b >> 2) & 0x38));
  332. ptr[0] = (uchar)((a<<1) & 0xf8);
  333. }
  334. }
  335. // Read remaining bytes to align to 32 bits...
  336. for (temp = w() * 2; temp & 3; temp ++) {
  337. getc(fp);
  338. }
  339. break;
  340. case 24 : // 24-bit RGB
  341. for (x = w(); x > 0; x --, ptr += bDepth) {
  342. ptr[2] = (uchar)getc(fp);
  343. ptr[1] = (uchar)getc(fp);
  344. ptr[0] = (uchar)getc(fp);
  345. }
  346. // Read remaining bytes to align to 32 bits...
  347. for (temp = w() * 3; temp & 3; temp ++) {
  348. getc(fp);
  349. }
  350. break;
  351. case 32 : // 32-bit RGBA
  352. for (x = w(); x > 0; x --, ptr += bDepth) {
  353. ptr[2] = (uchar)getc(fp);
  354. ptr[1] = (uchar)getc(fp);
  355. ptr[0] = (uchar)getc(fp);
  356. ptr[3] = (uchar)getc(fp);
  357. }
  358. break;
  359. }
  360. }
  361. if (havemask) {
  362. for (y = h() - 1; y >= 0; y --) {
  363. ptr = (uchar *)array + y * w() * d() + 3;
  364. for (x = w(), bit = 128; x > 0; x --, ptr+=bDepth) {
  365. if (bit == 128) byte = (uchar)getc(fp);
  366. if (byte & bit)
  367. *ptr = 0;
  368. else
  369. *ptr = 255;
  370. if (bit > 1)
  371. bit >>= 1;
  372. else
  373. bit = 128;
  374. }
  375. // Read remaining bytes to align to 32 bits...
  376. for (temp = (w() + 7) / 8; temp & 3; temp ++)
  377. getc(fp);
  378. }
  379. }
  380. // Close the file and return...
  381. fclose(fp);
  382. }
  383. //
  384. // 'read_word()' - Read a 16-bit unsigned integer.
  385. //
  386. static unsigned short // O - 16-bit unsigned integer
  387. read_word(FILE *fp) { // I - File to read from
  388. unsigned char b0, b1; // Bytes from file
  389. b0 = (uchar)getc(fp);
  390. b1 = (uchar)getc(fp);
  391. return ((b1 << 8) | b0);
  392. }
  393. //
  394. // 'read_dword()' - Read a 32-bit unsigned integer.
  395. //
  396. static unsigned int // O - 32-bit unsigned integer
  397. read_dword(FILE *fp) { // I - File to read from
  398. unsigned char b0, b1, b2, b3; // Bytes from file
  399. b0 = (uchar)getc(fp);
  400. b1 = (uchar)getc(fp);
  401. b2 = (uchar)getc(fp);
  402. b3 = (uchar)getc(fp);
  403. return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
  404. }
  405. //
  406. // 'read_long()' - Read a 32-bit signed integer.
  407. //
  408. static int // O - 32-bit signed integer
  409. read_long(FILE *fp) { // I - File to read from
  410. unsigned char b0, b1, b2, b3; // Bytes from file
  411. b0 = (uchar)getc(fp);
  412. b1 = (uchar)getc(fp);
  413. b2 = (uchar)getc(fp);
  414. b3 = (uchar)getc(fp);
  415. return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
  416. }
  417. //
  418. // End of "$Id: Fl_BMP_Image.cxx 7903 2010-11-28 21:06:39Z matt $".
  419. //