rdbmp.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. /*
  2. * rdbmp.c
  3. *
  4. * This file was part of the Independent JPEG Group's software:
  5. * Copyright (C) 1994-1996, Thomas G. Lane.
  6. * Modified 2009-2017 by Guido Vollbeding.
  7. * libjpeg-turbo Modifications:
  8. * Modified 2011 by Siarhei Siamashka.
  9. * Copyright (C) 2015, 2017-2018, D. R. Commander.
  10. * For conditions of distribution and use, see the accompanying README.ijg
  11. * file.
  12. *
  13. * This file contains routines to read input images in Microsoft "BMP"
  14. * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
  15. * Currently, only 8-bit and 24-bit images are supported, not 1-bit or
  16. * 4-bit (feeding such low-depth images into JPEG would be silly anyway).
  17. * Also, we don't support RLE-compressed files.
  18. *
  19. * These routines may need modification for non-Unix environments or
  20. * specialized applications. As they stand, they assume input from
  21. * an ordinary stdio stream. They further assume that reading begins
  22. * at the start of the file; start_input may need work if the
  23. * user interface has already read some data (e.g., to determine that
  24. * the file is indeed BMP format).
  25. *
  26. * This code contributed by James Arthur Boucher.
  27. */
  28. #include "cmyk.h"
  29. #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
  30. #ifdef BMP_SUPPORTED
  31. /* Macros to deal with unsigned chars as efficiently as compiler allows */
  32. #ifdef HAVE_UNSIGNED_CHAR
  33. typedef unsigned char U_CHAR;
  34. #define UCH(x) ((int)(x))
  35. #else /* !HAVE_UNSIGNED_CHAR */
  36. #ifdef __CHAR_UNSIGNED__
  37. typedef char U_CHAR;
  38. #define UCH(x) ((int)(x))
  39. #else
  40. typedef char U_CHAR;
  41. #define UCH(x) ((int)(x) & 0xFF)
  42. #endif
  43. #endif /* HAVE_UNSIGNED_CHAR */
  44. #define ReadOK(file, buffer, len) \
  45. (JFREAD(file, buffer, len) == ((size_t)(len)))
  46. static int alpha_index[JPEG_NUMCS] = {
  47. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
  48. };
  49. /* Private version of data source object */
  50. typedef struct _bmp_source_struct *bmp_source_ptr;
  51. typedef struct _bmp_source_struct {
  52. struct cjpeg_source_struct pub; /* public fields */
  53. j_compress_ptr cinfo; /* back link saves passing separate parm */
  54. JSAMPARRAY colormap; /* BMP colormap (converted to my format) */
  55. jvirt_sarray_ptr whole_image; /* Needed to reverse row order */
  56. JDIMENSION source_row; /* Current source row number */
  57. JDIMENSION row_width; /* Physical width of scanlines in file */
  58. int bits_per_pixel; /* remembers 8- or 24-bit format */
  59. int cmap_length; /* colormap length */
  60. boolean use_inversion_array; /* TRUE = preload the whole image, which is
  61. stored in bottom-up order, and feed it to
  62. the calling program in top-down order
  63. FALSE = the calling program will maintain
  64. its own image buffer and read the rows in
  65. bottom-up order */
  66. U_CHAR *iobuffer; /* I/O buffer (used to buffer a single row from
  67. disk if use_inversion_array == FALSE) */
  68. } bmp_source_struct;
  69. LOCAL(int)
  70. read_byte(bmp_source_ptr sinfo)
  71. /* Read next byte from BMP file */
  72. {
  73. register FILE *infile = sinfo->pub.input_file;
  74. register int c;
  75. if ((c = getc(infile)) == EOF)
  76. ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
  77. return c;
  78. }
  79. LOCAL(void)
  80. read_colormap(bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
  81. /* Read the colormap from a BMP file */
  82. {
  83. int i, gray = 1;
  84. switch (mapentrysize) {
  85. case 3:
  86. /* BGR format (occurs in OS/2 files) */
  87. for (i = 0; i < cmaplen; i++) {
  88. sinfo->colormap[2][i] = (JSAMPLE)read_byte(sinfo);
  89. sinfo->colormap[1][i] = (JSAMPLE)read_byte(sinfo);
  90. sinfo->colormap[0][i] = (JSAMPLE)read_byte(sinfo);
  91. if (sinfo->colormap[2][i] != sinfo->colormap[1][i] ||
  92. sinfo->colormap[1][i] != sinfo->colormap[0][i])
  93. gray = 0;
  94. }
  95. break;
  96. case 4:
  97. /* BGR0 format (occurs in MS Windows files) */
  98. for (i = 0; i < cmaplen; i++) {
  99. sinfo->colormap[2][i] = (JSAMPLE)read_byte(sinfo);
  100. sinfo->colormap[1][i] = (JSAMPLE)read_byte(sinfo);
  101. sinfo->colormap[0][i] = (JSAMPLE)read_byte(sinfo);
  102. (void)read_byte(sinfo);
  103. if (sinfo->colormap[2][i] != sinfo->colormap[1][i] ||
  104. sinfo->colormap[1][i] != sinfo->colormap[0][i])
  105. gray = 0;
  106. }
  107. break;
  108. default:
  109. ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP);
  110. break;
  111. }
  112. if (sinfo->cinfo->in_color_space == JCS_UNKNOWN && gray)
  113. sinfo->cinfo->in_color_space = JCS_GRAYSCALE;
  114. if (sinfo->cinfo->in_color_space == JCS_GRAYSCALE && !gray)
  115. ERREXIT(sinfo->cinfo, JERR_BAD_IN_COLORSPACE);
  116. }
  117. /*
  118. * Read one row of pixels.
  119. * The image has been read into the whole_image array, but is otherwise
  120. * unprocessed. We must read it out in top-to-bottom row order, and if
  121. * it is an 8-bit image, we must expand colormapped pixels to 24bit format.
  122. */
  123. METHODDEF(JDIMENSION)
  124. get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  125. /* This version is for reading 8-bit colormap indexes */
  126. {
  127. bmp_source_ptr source = (bmp_source_ptr)sinfo;
  128. register JSAMPARRAY colormap = source->colormap;
  129. int cmaplen = source->cmap_length;
  130. JSAMPARRAY image_ptr;
  131. register int t;
  132. register JSAMPROW inptr, outptr;
  133. register JDIMENSION col;
  134. if (source->use_inversion_array) {
  135. /* Fetch next row from virtual array */
  136. source->source_row--;
  137. image_ptr = (*cinfo->mem->access_virt_sarray)
  138. ((j_common_ptr)cinfo, source->whole_image,
  139. source->source_row, (JDIMENSION)1, FALSE);
  140. inptr = image_ptr[0];
  141. } else {
  142. if (!ReadOK(source->pub.input_file, source->iobuffer, source->row_width))
  143. ERREXIT(cinfo, JERR_INPUT_EOF);
  144. inptr = source->iobuffer;
  145. }
  146. /* Expand the colormap indexes to real data */
  147. outptr = source->pub.buffer[0];
  148. if (cinfo->in_color_space == JCS_GRAYSCALE) {
  149. for (col = cinfo->image_width; col > 0; col--) {
  150. t = GETJSAMPLE(*inptr++);
  151. if (t >= cmaplen)
  152. ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
  153. *outptr++ = colormap[0][t];
  154. }
  155. } else if (cinfo->in_color_space == JCS_CMYK) {
  156. for (col = cinfo->image_width; col > 0; col--) {
  157. t = GETJSAMPLE(*inptr++);
  158. if (t >= cmaplen)
  159. ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
  160. rgb_to_cmyk(colormap[0][t], colormap[1][t], colormap[2][t], outptr,
  161. outptr + 1, outptr + 2, outptr + 3);
  162. outptr += 4;
  163. }
  164. } else {
  165. register int rindex = rgb_red[cinfo->in_color_space];
  166. register int gindex = rgb_green[cinfo->in_color_space];
  167. register int bindex = rgb_blue[cinfo->in_color_space];
  168. register int aindex = alpha_index[cinfo->in_color_space];
  169. register int ps = rgb_pixelsize[cinfo->in_color_space];
  170. if (aindex >= 0) {
  171. for (col = cinfo->image_width; col > 0; col--) {
  172. t = GETJSAMPLE(*inptr++);
  173. if (t >= cmaplen)
  174. ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
  175. outptr[rindex] = colormap[0][t];
  176. outptr[gindex] = colormap[1][t];
  177. outptr[bindex] = colormap[2][t];
  178. outptr[aindex] = 0xFF;
  179. outptr += ps;
  180. }
  181. } else {
  182. for (col = cinfo->image_width; col > 0; col--) {
  183. t = GETJSAMPLE(*inptr++);
  184. if (t >= cmaplen)
  185. ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
  186. outptr[rindex] = colormap[0][t];
  187. outptr[gindex] = colormap[1][t];
  188. outptr[bindex] = colormap[2][t];
  189. outptr += ps;
  190. }
  191. }
  192. }
  193. return 1;
  194. }
  195. METHODDEF(JDIMENSION)
  196. get_24bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  197. /* This version is for reading 24-bit pixels */
  198. {
  199. bmp_source_ptr source = (bmp_source_ptr)sinfo;
  200. JSAMPARRAY image_ptr;
  201. register JSAMPROW inptr, outptr;
  202. register JDIMENSION col;
  203. if (source->use_inversion_array) {
  204. /* Fetch next row from virtual array */
  205. source->source_row--;
  206. image_ptr = (*cinfo->mem->access_virt_sarray)
  207. ((j_common_ptr)cinfo, source->whole_image,
  208. source->source_row, (JDIMENSION)1, FALSE);
  209. inptr = image_ptr[0];
  210. } else {
  211. if (!ReadOK(source->pub.input_file, source->iobuffer, source->row_width))
  212. ERREXIT(cinfo, JERR_INPUT_EOF);
  213. inptr = source->iobuffer;
  214. }
  215. /* Transfer data. Note source values are in BGR order
  216. * (even though Microsoft's own documents say the opposite).
  217. */
  218. outptr = source->pub.buffer[0];
  219. if (cinfo->in_color_space == JCS_EXT_BGR) {
  220. MEMCOPY(outptr, inptr, source->row_width);
  221. } else if (cinfo->in_color_space == JCS_CMYK) {
  222. for (col = cinfo->image_width; col > 0; col--) {
  223. /* can omit GETJSAMPLE() safely */
  224. JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
  225. rgb_to_cmyk(r, g, b, outptr, outptr + 1, outptr + 2, outptr + 3);
  226. outptr += 4;
  227. }
  228. } else {
  229. register int rindex = rgb_red[cinfo->in_color_space];
  230. register int gindex = rgb_green[cinfo->in_color_space];
  231. register int bindex = rgb_blue[cinfo->in_color_space];
  232. register int aindex = alpha_index[cinfo->in_color_space];
  233. register int ps = rgb_pixelsize[cinfo->in_color_space];
  234. if (aindex >= 0) {
  235. for (col = cinfo->image_width; col > 0; col--) {
  236. outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
  237. outptr[gindex] = *inptr++;
  238. outptr[rindex] = *inptr++;
  239. outptr[aindex] = 0xFF;
  240. outptr += ps;
  241. }
  242. } else {
  243. for (col = cinfo->image_width; col > 0; col--) {
  244. outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
  245. outptr[gindex] = *inptr++;
  246. outptr[rindex] = *inptr++;
  247. outptr += ps;
  248. }
  249. }
  250. }
  251. return 1;
  252. }
  253. METHODDEF(JDIMENSION)
  254. get_32bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  255. /* This version is for reading 32-bit pixels */
  256. {
  257. bmp_source_ptr source = (bmp_source_ptr)sinfo;
  258. JSAMPARRAY image_ptr;
  259. register JSAMPROW inptr, outptr;
  260. register JDIMENSION col;
  261. if (source->use_inversion_array) {
  262. /* Fetch next row from virtual array */
  263. source->source_row--;
  264. image_ptr = (*cinfo->mem->access_virt_sarray)
  265. ((j_common_ptr)cinfo, source->whole_image,
  266. source->source_row, (JDIMENSION)1, FALSE);
  267. inptr = image_ptr[0];
  268. } else {
  269. if (!ReadOK(source->pub.input_file, source->iobuffer, source->row_width))
  270. ERREXIT(cinfo, JERR_INPUT_EOF);
  271. inptr = source->iobuffer;
  272. }
  273. /* Transfer data. Note source values are in BGR order
  274. * (even though Microsoft's own documents say the opposite).
  275. */
  276. outptr = source->pub.buffer[0];
  277. if (cinfo->in_color_space == JCS_EXT_BGRX ||
  278. cinfo->in_color_space == JCS_EXT_BGRA) {
  279. MEMCOPY(outptr, inptr, source->row_width);
  280. } else if (cinfo->in_color_space == JCS_CMYK) {
  281. for (col = cinfo->image_width; col > 0; col--) {
  282. /* can omit GETJSAMPLE() safely */
  283. JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
  284. rgb_to_cmyk(r, g, b, outptr, outptr + 1, outptr + 2, outptr + 3);
  285. inptr++; /* skip the 4th byte (Alpha channel) */
  286. outptr += 4;
  287. }
  288. } else {
  289. register int rindex = rgb_red[cinfo->in_color_space];
  290. register int gindex = rgb_green[cinfo->in_color_space];
  291. register int bindex = rgb_blue[cinfo->in_color_space];
  292. register int aindex = alpha_index[cinfo->in_color_space];
  293. register int ps = rgb_pixelsize[cinfo->in_color_space];
  294. if (aindex >= 0) {
  295. for (col = cinfo->image_width; col > 0; col--) {
  296. outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
  297. outptr[gindex] = *inptr++;
  298. outptr[rindex] = *inptr++;
  299. outptr[aindex] = *inptr++;
  300. outptr += ps;
  301. }
  302. } else {
  303. for (col = cinfo->image_width; col > 0; col--) {
  304. outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
  305. outptr[gindex] = *inptr++;
  306. outptr[rindex] = *inptr++;
  307. inptr++; /* skip the 4th byte (Alpha channel) */
  308. outptr += ps;
  309. }
  310. }
  311. }
  312. return 1;
  313. }
  314. /*
  315. * This method loads the image into whole_image during the first call on
  316. * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call
  317. * get_8bit_row, get_24bit_row, or get_32bit_row on subsequent calls.
  318. */
  319. METHODDEF(JDIMENSION)
  320. preload_image(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  321. {
  322. bmp_source_ptr source = (bmp_source_ptr)sinfo;
  323. register FILE *infile = source->pub.input_file;
  324. register JSAMPROW out_ptr;
  325. JSAMPARRAY image_ptr;
  326. JDIMENSION row;
  327. cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
  328. /* Read the data into a virtual array in input-file row order. */
  329. for (row = 0; row < cinfo->image_height; row++) {
  330. if (progress != NULL) {
  331. progress->pub.pass_counter = (long)row;
  332. progress->pub.pass_limit = (long)cinfo->image_height;
  333. (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
  334. }
  335. image_ptr = (*cinfo->mem->access_virt_sarray)
  336. ((j_common_ptr)cinfo, source->whole_image, row, (JDIMENSION)1, TRUE);
  337. out_ptr = image_ptr[0];
  338. if (fread(out_ptr, 1, source->row_width, infile) != source->row_width) {
  339. if (feof(infile))
  340. ERREXIT(cinfo, JERR_INPUT_EOF);
  341. else
  342. ERREXIT(cinfo, JERR_FILE_READ);
  343. }
  344. }
  345. if (progress != NULL)
  346. progress->completed_extra_passes++;
  347. /* Set up to read from the virtual array in top-to-bottom order */
  348. switch (source->bits_per_pixel) {
  349. case 8:
  350. source->pub.get_pixel_rows = get_8bit_row;
  351. break;
  352. case 24:
  353. source->pub.get_pixel_rows = get_24bit_row;
  354. break;
  355. case 32:
  356. source->pub.get_pixel_rows = get_32bit_row;
  357. break;
  358. default:
  359. ERREXIT(cinfo, JERR_BMP_BADDEPTH);
  360. }
  361. source->source_row = cinfo->image_height;
  362. /* And read the first row */
  363. return (*source->pub.get_pixel_rows) (cinfo, sinfo);
  364. }
  365. /*
  366. * Read the file header; return image size and component count.
  367. */
  368. METHODDEF(void)
  369. start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  370. {
  371. bmp_source_ptr source = (bmp_source_ptr)sinfo;
  372. U_CHAR bmpfileheader[14];
  373. U_CHAR bmpinfoheader[64];
  374. #define GET_2B(array, offset) \
  375. ((unsigned short)UCH(array[offset]) + \
  376. (((unsigned short)UCH(array[offset + 1])) << 8))
  377. #define GET_4B(array, offset) \
  378. ((unsigned int)UCH(array[offset]) + \
  379. (((unsigned int)UCH(array[offset + 1])) << 8) + \
  380. (((unsigned int)UCH(array[offset + 2])) << 16) + \
  381. (((unsigned int)UCH(array[offset + 3])) << 24))
  382. unsigned int bfOffBits;
  383. unsigned int headerSize;
  384. int biWidth;
  385. int biHeight;
  386. unsigned short biPlanes;
  387. unsigned int biCompression;
  388. int biXPelsPerMeter, biYPelsPerMeter;
  389. unsigned int biClrUsed = 0;
  390. int mapentrysize = 0; /* 0 indicates no colormap */
  391. int bPad;
  392. JDIMENSION row_width = 0;
  393. /* Read and verify the bitmap file header */
  394. if (!ReadOK(source->pub.input_file, bmpfileheader, 14))
  395. ERREXIT(cinfo, JERR_INPUT_EOF);
  396. if (GET_2B(bmpfileheader, 0) != 0x4D42) /* 'BM' */
  397. ERREXIT(cinfo, JERR_BMP_NOT);
  398. bfOffBits = GET_4B(bmpfileheader, 10);
  399. /* We ignore the remaining fileheader fields */
  400. /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
  401. * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which.
  402. */
  403. if (!ReadOK(source->pub.input_file, bmpinfoheader, 4))
  404. ERREXIT(cinfo, JERR_INPUT_EOF);
  405. headerSize = GET_4B(bmpinfoheader, 0);
  406. if (headerSize < 12 || headerSize > 64)
  407. ERREXIT(cinfo, JERR_BMP_BADHEADER);
  408. if (!ReadOK(source->pub.input_file, bmpinfoheader + 4, headerSize - 4))
  409. ERREXIT(cinfo, JERR_INPUT_EOF);
  410. switch (headerSize) {
  411. case 12:
  412. /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */
  413. biWidth = (int)GET_2B(bmpinfoheader, 4);
  414. biHeight = (int)GET_2B(bmpinfoheader, 6);
  415. biPlanes = GET_2B(bmpinfoheader, 8);
  416. source->bits_per_pixel = (int)GET_2B(bmpinfoheader, 10);
  417. switch (source->bits_per_pixel) {
  418. case 8: /* colormapped image */
  419. mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */
  420. TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, biWidth, biHeight);
  421. break;
  422. case 24: /* RGB image */
  423. TRACEMS2(cinfo, 1, JTRC_BMP_OS2, biWidth, biHeight);
  424. break;
  425. default:
  426. ERREXIT(cinfo, JERR_BMP_BADDEPTH);
  427. break;
  428. }
  429. break;
  430. case 40:
  431. case 64:
  432. /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
  433. /* or OS/2 2.x header, which has additional fields that we ignore */
  434. biWidth = (int)GET_4B(bmpinfoheader, 4);
  435. biHeight = (int)GET_4B(bmpinfoheader, 8);
  436. biPlanes = GET_2B(bmpinfoheader, 12);
  437. source->bits_per_pixel = (int)GET_2B(bmpinfoheader, 14);
  438. biCompression = GET_4B(bmpinfoheader, 16);
  439. biXPelsPerMeter = (int)GET_4B(bmpinfoheader, 24);
  440. biYPelsPerMeter = (int)GET_4B(bmpinfoheader, 28);
  441. biClrUsed = GET_4B(bmpinfoheader, 32);
  442. /* biSizeImage, biClrImportant fields are ignored */
  443. switch (source->bits_per_pixel) {
  444. case 8: /* colormapped image */
  445. mapentrysize = 4; /* Windows uses RGBQUAD colormap */
  446. TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, biWidth, biHeight);
  447. break;
  448. case 24: /* RGB image */
  449. TRACEMS2(cinfo, 1, JTRC_BMP, biWidth, biHeight);
  450. break;
  451. case 32: /* RGB image + Alpha channel */
  452. TRACEMS2(cinfo, 1, JTRC_BMP, biWidth, biHeight);
  453. break;
  454. default:
  455. ERREXIT(cinfo, JERR_BMP_BADDEPTH);
  456. break;
  457. }
  458. if (biCompression != 0)
  459. ERREXIT(cinfo, JERR_BMP_COMPRESSED);
  460. if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) {
  461. /* Set JFIF density parameters from the BMP data */
  462. cinfo->X_density = (UINT16)(biXPelsPerMeter / 100); /* 100 cm per meter */
  463. cinfo->Y_density = (UINT16)(biYPelsPerMeter / 100);
  464. cinfo->density_unit = 2; /* dots/cm */
  465. }
  466. break;
  467. default:
  468. ERREXIT(cinfo, JERR_BMP_BADHEADER);
  469. return;
  470. }
  471. if (biWidth <= 0 || biHeight <= 0)
  472. ERREXIT(cinfo, JERR_BMP_EMPTY);
  473. if (biPlanes != 1)
  474. ERREXIT(cinfo, JERR_BMP_BADPLANES);
  475. /* Compute distance to bitmap data --- will adjust for colormap below */
  476. bPad = bfOffBits - (headerSize + 14);
  477. /* Read the colormap, if any */
  478. if (mapentrysize > 0) {
  479. if (biClrUsed <= 0)
  480. biClrUsed = 256; /* assume it's 256 */
  481. else if (biClrUsed > 256)
  482. ERREXIT(cinfo, JERR_BMP_BADCMAP);
  483. /* Allocate space to store the colormap */
  484. source->colormap = (*cinfo->mem->alloc_sarray)
  485. ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)biClrUsed, (JDIMENSION)3);
  486. source->cmap_length = (int)biClrUsed;
  487. /* and read it from the file */
  488. read_colormap(source, (int)biClrUsed, mapentrysize);
  489. /* account for size of colormap */
  490. bPad -= biClrUsed * mapentrysize;
  491. }
  492. /* Skip any remaining pad bytes */
  493. if (bPad < 0) /* incorrect bfOffBits value? */
  494. ERREXIT(cinfo, JERR_BMP_BADHEADER);
  495. while (--bPad >= 0) {
  496. (void)read_byte(source);
  497. }
  498. /* Compute row width in file, including padding to 4-byte boundary */
  499. switch (source->bits_per_pixel) {
  500. case 8:
  501. if (cinfo->in_color_space == JCS_UNKNOWN)
  502. cinfo->in_color_space = JCS_EXT_RGB;
  503. if (IsExtRGB(cinfo->in_color_space))
  504. cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
  505. else if (cinfo->in_color_space == JCS_GRAYSCALE)
  506. cinfo->input_components = 1;
  507. else if (cinfo->in_color_space == JCS_CMYK)
  508. cinfo->input_components = 4;
  509. else
  510. ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
  511. row_width = (JDIMENSION)biWidth;
  512. break;
  513. case 24:
  514. if (cinfo->in_color_space == JCS_UNKNOWN)
  515. cinfo->in_color_space = JCS_EXT_BGR;
  516. if (IsExtRGB(cinfo->in_color_space))
  517. cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
  518. else if (cinfo->in_color_space == JCS_CMYK)
  519. cinfo->input_components = 4;
  520. else
  521. ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
  522. row_width = (JDIMENSION)(biWidth * 3);
  523. break;
  524. case 32:
  525. if (cinfo->in_color_space == JCS_UNKNOWN)
  526. cinfo->in_color_space = JCS_EXT_BGRA;
  527. if (IsExtRGB(cinfo->in_color_space))
  528. cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
  529. else if (cinfo->in_color_space == JCS_CMYK)
  530. cinfo->input_components = 4;
  531. else
  532. ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
  533. row_width = (JDIMENSION)(biWidth * 4);
  534. break;
  535. default:
  536. ERREXIT(cinfo, JERR_BMP_BADDEPTH);
  537. }
  538. while ((row_width & 3) != 0) row_width++;
  539. source->row_width = row_width;
  540. if (source->use_inversion_array) {
  541. /* Allocate space for inversion array, prepare for preload pass */
  542. source->whole_image = (*cinfo->mem->request_virt_sarray)
  543. ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE,
  544. row_width, (JDIMENSION)biHeight, (JDIMENSION)1);
  545. source->pub.get_pixel_rows = preload_image;
  546. if (cinfo->progress != NULL) {
  547. cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
  548. progress->total_extra_passes++; /* count file input as separate pass */
  549. }
  550. } else {
  551. source->iobuffer = (U_CHAR *)
  552. (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, row_width);
  553. switch (source->bits_per_pixel) {
  554. case 8:
  555. source->pub.get_pixel_rows = get_8bit_row;
  556. break;
  557. case 24:
  558. source->pub.get_pixel_rows = get_24bit_row;
  559. break;
  560. case 32:
  561. source->pub.get_pixel_rows = get_32bit_row;
  562. break;
  563. default:
  564. ERREXIT(cinfo, JERR_BMP_BADDEPTH);
  565. }
  566. }
  567. /* Ensure that biWidth * cinfo->input_components doesn't exceed the maximum
  568. value of the JDIMENSION type. This is only a danger with BMP files, since
  569. their width and height fields are 32-bit integers. */
  570. if ((unsigned long long)biWidth *
  571. (unsigned long long)cinfo->input_components > 0xFFFFFFFFULL)
  572. ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
  573. /* Allocate one-row buffer for returned data */
  574. source->pub.buffer = (*cinfo->mem->alloc_sarray)
  575. ((j_common_ptr)cinfo, JPOOL_IMAGE,
  576. (JDIMENSION)(biWidth * cinfo->input_components), (JDIMENSION)1);
  577. source->pub.buffer_height = 1;
  578. cinfo->data_precision = 8;
  579. cinfo->image_width = (JDIMENSION)biWidth;
  580. cinfo->image_height = (JDIMENSION)biHeight;
  581. }
  582. /*
  583. * Finish up at the end of the file.
  584. */
  585. METHODDEF(void)
  586. finish_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  587. {
  588. /* no work */
  589. }
  590. /*
  591. * The module selection routine for BMP format input.
  592. */
  593. GLOBAL(cjpeg_source_ptr)
  594. jinit_read_bmp(j_compress_ptr cinfo, boolean use_inversion_array)
  595. {
  596. bmp_source_ptr source;
  597. /* Create module interface object */
  598. source = (bmp_source_ptr)
  599. (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
  600. sizeof(bmp_source_struct));
  601. source->cinfo = cinfo; /* make back link for subroutines */
  602. /* Fill in method ptrs, except get_pixel_rows which start_input sets */
  603. source->pub.start_input = start_input_bmp;
  604. source->pub.finish_input = finish_input_bmp;
  605. source->use_inversion_array = use_inversion_array;
  606. return (cjpeg_source_ptr)source;
  607. }
  608. #endif /* BMP_SUPPORTED */