rdbmp.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. Unit RdBmp;
  2. { rdbmp.c
  3. Copyright (C) 1994-1996, Thomas G. Lane.
  4. This file is part of the Independent JPEG Group's software.
  5. For conditions of distribution and use, see the accompanying README file.
  6. This file contains routines to read input images in Microsoft "BMP"
  7. format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
  8. Currently, only 8-bit and 24-bit images are supported, not 1-bit or
  9. 4-bit (feeding such low-depth images into JPEG would be silly anyway).
  10. Also, we don't support RLE-compressed files.
  11. These routines may need modification for non-Unix environments or
  12. specialized applications. As they stand, they assume input from
  13. an ordinary stdio stream. They further assume that reading begins
  14. at the start of the file; start_input may need work if the
  15. user interface has already read some data (e.g., to determine that
  16. the file is indeed BMP format).
  17. This code contributed by James Arthur Boucher. }
  18. interface
  19. {$I jconfig.inc}
  20. uses
  21. jmorecfg,
  22. jpeglib,
  23. jinclude,
  24. jdeferr,
  25. jerror,
  26. cdjpeg; { Common decls for cjpeg/djpeg applications }
  27. { The module selection routine for BMP format input. }
  28. {GLOBAL}
  29. function jinit_read_bmp (cinfo : j_compress_ptr) : cjpeg_source_ptr;
  30. implementation
  31. { Macros to deal with unsigned chars as efficiently as compiler allows }
  32. {$define HAVE_UNSIGNED_CHAR}
  33. {$ifdef HAVE_UNSIGNED_CHAR}
  34. type
  35. U_CHAR = byte;
  36. UCH = int;
  37. {$else} { !HAVE_UNSIGNED_CHAR }
  38. {$ifdef CHAR_IS_UNSIGNED}
  39. type
  40. U_CHAR = char;
  41. UCH = int;
  42. {$else}
  43. type
  44. U_CHAR = char;
  45. UCH = int(x) and $FF
  46. {$endif}
  47. {$endif} { HAVE_UNSIGNED_CHAR }
  48. { Private version of data source object }
  49. type
  50. bmp_source_ptr = ^bmp_source_struct;
  51. bmp_source_struct = record
  52. pub : cjpeg_source_struct; { public fields }
  53. cinfo : j_compress_ptr; { back link saves passing separate parm }
  54. colormap : JSAMPARRAY; { BMP colormap (converted to my format) }
  55. whole_image : jvirt_sarray_ptr; { Needed to reverse row order }
  56. source_row : JDIMENSION; { Current source row number }
  57. row_width : JDIMENSION; { Physical width of scanlines in file }
  58. bits_per_pixel : int; { remembers 8- or 24-bit format }
  59. end; { bmp_source_struct }
  60. {LOCAL}
  61. function read_byte (sinfo : bmp_source_ptr) : int;
  62. { Read next byte from BMP file }
  63. var
  64. {register} infile : FILEptr;
  65. {register} c : byte;
  66. begin
  67. infile := sinfo^.pub.input_file;
  68. if JFREAD(infile, @c, 1) <> size_t(1) then
  69. ERREXIT(j_common_ptr(sinfo^.cinfo), JERR_INPUT_EOF);
  70. read_byte := c;
  71. end;
  72. {LOCAL}
  73. procedure read_colormap (sinfo : bmp_source_ptr;
  74. cmaplen : int;
  75. mapentrysize : int);
  76. { Read the colormap from a BMP file }
  77. var
  78. i : int;
  79. begin
  80. case (mapentrysize) of
  81. 3:{ BGR format (occurs in OS/2 files) }
  82. for i := 0 to pred(cmaplen) do
  83. begin
  84. sinfo^.colormap^[2]^[i] := JSAMPLE (read_byte(sinfo));
  85. sinfo^.colormap^[1]^[i] := JSAMPLE (read_byte(sinfo));
  86. sinfo^.colormap^[0]^[i] := JSAMPLE (read_byte(sinfo));
  87. end;
  88. 4:{ BGR0 format (occurs in MS Windows files) }
  89. for i := 0 to pred(cmaplen) do
  90. begin
  91. sinfo^.colormap^[2]^[i] := JSAMPLE (read_byte(sinfo));
  92. sinfo^.colormap^[1]^[i] := JSAMPLE (read_byte(sinfo));
  93. sinfo^.colormap^[0]^[i] := JSAMPLE (read_byte(sinfo));
  94. {void} read_byte(sinfo);
  95. end;
  96. else
  97. ERREXIT(j_common_ptr(sinfo^.cinfo), JERR_BMP_BADCMAP);
  98. end;
  99. end;
  100. { Read one row of pixels.
  101. The image has been read into the whole_image array, but is otherwise
  102. unprocessed. We must read it out in top-to-bottom row order, and if
  103. it is an 8-bit image, we must expand colormapped pixels to 24bit format. }
  104. {METHODDEF}
  105. function get_8bit_row (cinfo : j_compress_ptr;
  106. sinfo : cjpeg_source_ptr) : JDIMENSION; far;
  107. { This version is for reading 8-bit colormap indexes }
  108. var
  109. source : bmp_source_ptr;
  110. {register} colormap : JSAMPARRAY;
  111. image_ptr : JSAMPARRAY;
  112. {register} t : int;
  113. {register} inptr, outptr : JSAMPLE_PTR;
  114. {register} col : JDIMENSION;
  115. begin
  116. source := bmp_source_ptr (sinfo);
  117. colormap := source^.colormap;
  118. { Fetch next row from virtual array }
  119. Dec(source^.source_row);
  120. image_ptr := cinfo^.mem^.access_virt_sarray(
  121. j_common_ptr (cinfo), source^.whole_image,
  122. source^.source_row, JDIMENSION (1), FALSE);
  123. { Expand the colormap indexes to real data }
  124. inptr := JSAMPLE_PTR(image_ptr^[0]);
  125. outptr := JSAMPLE_PTR(source^.pub.buffer^[0]);
  126. for col := pred(cinfo^.image_width) downto 0 do
  127. begin
  128. t := GETJSAMPLE(inptr^);
  129. Inc(inptr);
  130. outptr^ := colormap^[0]^[t]; { can omit GETJSAMPLE() safely }
  131. Inc(outptr);
  132. outptr^ := colormap^[1]^[t];
  133. Inc(outptr);
  134. outptr^ := colormap^[2]^[t];
  135. Inc(outptr);
  136. end;
  137. get_8bit_row := 1;
  138. end;
  139. {METHODDEF}
  140. function get_24bit_row (cinfo : j_compress_ptr;
  141. sinfo : cjpeg_source_ptr) : JDIMENSION; far;
  142. { This version is for reading 24-bit pixels }
  143. var
  144. source : bmp_source_ptr;
  145. image_ptr : JSAMPARRAY;
  146. {register} inptr : JSAMPLE_PTR;
  147. {register} outptr : JSAMPROW;
  148. {register} col : JDIMENSION;
  149. begin
  150. source := bmp_source_ptr (sinfo);
  151. { Fetch next row from virtual array }
  152. Dec(source^.source_row);
  153. image_ptr := cinfo^.mem^.access_virt_sarray (
  154. j_common_ptr (cinfo), source^.whole_image,
  155. source^.source_row, JDIMENSION (1), FALSE);
  156. { Transfer data. Note source values are in BGR order
  157. (even though Microsoft's own documents say the opposite). }
  158. inptr := JSAMPLE_PTR(image_ptr^[0]);
  159. outptr := source^.pub.buffer^[0];
  160. for col := pred(cinfo^.image_width) downto 0 do
  161. begin
  162. outptr^[2] := inptr^; { can omit GETJSAMPLE() safely }
  163. Inc(inptr);
  164. outptr^[1] := inptr^;
  165. Inc(inptr);
  166. outptr^[0] := inptr^;
  167. Inc(inptr);
  168. Inc(JSAMPLE_PTR(outptr), 3);
  169. end;
  170. get_24bit_row := 1;
  171. end;
  172. { This method loads the image into whole_image during the first call on
  173. get_pixel_rows. The get_pixel_rows pointer is then adjusted to call
  174. get_8bit_row or get_24bit_row on subsequent calls. }
  175. {METHODDEF}
  176. function preload_image (cinfo : j_compress_ptr;
  177. sinfo : cjpeg_source_ptr) : JDIMENSION; far;
  178. var
  179. source : bmp_source_ptr;
  180. {register} infile : FILEptr;
  181. {$IFDEF Original}
  182. {register} c : int;
  183. {$ENDIF}
  184. {register} out_ptr : JSAMPLE_PTR;
  185. image_ptr : JSAMPARRAY;
  186. row : JDIMENSION;
  187. {$IFDEF Original}
  188. col : JDIMENSION;
  189. {$ENDIF}
  190. progress : cd_progress_ptr;
  191. begin
  192. source := bmp_source_ptr (sinfo);
  193. infile := source^.pub.input_file;
  194. progress := cd_progress_ptr (cinfo^.progress);
  195. { Read the data into a virtual array in input-file row order. }
  196. for row := 0 to pred(cinfo^.image_height) do
  197. begin
  198. if (progress <> NIL) then
  199. begin
  200. progress^.pub.pass_counter := long (row);
  201. progress^.pub.pass_limit := long (cinfo^.image_height);
  202. progress^.pub.progress_monitor (j_common_ptr (cinfo));
  203. end;
  204. image_ptr := cinfo^.mem^.access_virt_sarray (
  205. j_common_ptr (cinfo), source^.whole_image,
  206. row, JDIMENSION (1), TRUE);
  207. out_ptr := JSAMPLE_PTR(image_ptr^[0]);
  208. {$IFDEF Original}
  209. for col := pred(source^.row_width) downto 0 do
  210. begin
  211. { inline copy of read_byte() for speed }
  212. c := getc(infile);
  213. if (c = EOF) then
  214. ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
  215. out_ptr^ := JSAMPLE (c);
  216. Inc(out_ptr);
  217. end;
  218. {$ELSE}
  219. if JFREAD(infile, out_ptr, source^.row_width) <>
  220. size_t(source^.row_width) then
  221. ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
  222. {$ENDIF}
  223. end;
  224. if (progress <> NIL) then
  225. Inc(progress^.completed_extra_passes);
  226. { Set up to read from the virtual array in top-to-bottom order }
  227. case (source^.bits_per_pixel) of
  228. 8: source^.pub.get_pixel_rows := get_8bit_row;
  229. 24: source^.pub.get_pixel_rows := get_24bit_row;
  230. else
  231. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
  232. end;
  233. source^.source_row := cinfo^.image_height;
  234. { And read the first row }
  235. preload_image := source^.pub.get_pixel_rows (cinfo, sinfo);
  236. end;
  237. { Read the file header; return image size and component count. }
  238. {METHODDEF}
  239. procedure start_input_bmp (cinfo : j_compress_ptr;
  240. sinfo : cjpeg_source_ptr); far;
  241. var
  242. source : bmp_source_ptr;
  243. bmpfileheader : packed array[0..14-1] of U_CHAR;
  244. bmpinfoheader : packed array[0..64-1] of U_CHAR;
  245. bfOffBits : INT32 ;
  246. headerSize : INT32;
  247. biWidth : INT32; { initialize to avoid compiler warning }
  248. biHeight : INT32;
  249. biPlanes : uInt;
  250. biCompression : INT32;
  251. biXPelsPerMeter,biYPelsPerMeter : INT32;
  252. biClrUsed : INT32;
  253. mapentrysize : int;
  254. bPad : INT32;
  255. row_width : JDIMENSION;
  256. var
  257. progress : cd_progress_ptr;
  258. begin
  259. source := bmp_source_ptr (sinfo);
  260. biWidth := 0; { initialize to avoid compiler warning }
  261. biHeight := 0;
  262. biClrUsed := 0;
  263. mapentrysize := 0; { 0 indicates no colormap }
  264. { Read and verify the bitmap file header }
  265. if JFREAD(source^.pub.input_file, @bmpfileheader, 14) <> size_t (14) then
  266. ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
  267. { GET_2B(bmpfileheader, 0) }
  268. if (uInt(UCH(bmpfileheader[0]) +
  269. (uInt(UCH(bmpfileheader[0+1])) shl 8)) <> $4D42) then { 'BM' }
  270. ERREXIT(j_common_ptr(cinfo), JERR_BMP_NOT);
  271. bfOffBits := {INT32 ( GET_4B(bmpfileheader,10) );}
  272. INT32( INT32(UCH(bmpfileheader[10])) +
  273. ((INT32(UCH(bmpfileheader[10+1])) shl 8)) +
  274. ((INT32(UCH(bmpfileheader[10+2])) shl 16)) +
  275. ((INT32(UCH(bmpfileheader[10+3])) shl 24)));
  276. { We ignore the remaining fileheader fields }
  277. { The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
  278. or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which. }
  279. if JFREAD(source^.pub.input_file, @bmpinfoheader, 4) <> size_t(4) then
  280. ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
  281. headerSize := {INT32 (GET_4B(bmpinfoheader,0));}
  282. INT32( INT32(UCH(bmpinfoheader[0])) +
  283. ((INT32(UCH(bmpinfoheader[0+1])) shl 8)) +
  284. ((INT32(UCH(bmpinfoheader[0+2])) shl 16)) +
  285. ((INT32(UCH(bmpinfoheader[0+3])) shl 24)));
  286. if (headerSize < 12) or (headerSize > 64) then
  287. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADHEADER);
  288. if JFREAD(source^.pub.input_file,@bmpinfoheader[4],headerSize-4) <>
  289. size_t (headerSize-4) then
  290. ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
  291. case int(headerSize) of
  292. 12:begin
  293. { Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) }
  294. biWidth := {INT32 (GET_2B(bmpinfoheader,4));}
  295. INT32( uInt(UCH(bmpinfoheader[4])) +
  296. (uInt(UCH(bmpinfoheader[4+1])) shl 8) );
  297. biHeight := {INT32 (GET_2B(bmpinfoheader,6));}
  298. INT32( uInt(UCH(bmpinfoheader[6])) +
  299. (uInt(UCH(bmpinfoheader[6+1])) shl 8) );
  300. biPlanes := {GET_2B(bmpinfoheader,8);}
  301. uInt(UCH(bmpinfoheader[8])) +
  302. (uInt(UCH(bmpinfoheader[8+1])) shl 8);
  303. source^.bits_per_pixel := {int (GET_2B(bmpinfoheader,10));}
  304. int( uInt(UCH(bmpinfoheader[10])) +
  305. (uInt(UCH(bmpinfoheader[10+1])) shl 8));
  306. case (source^.bits_per_pixel) of
  307. 8: begin { colormapped image }
  308. mapentrysize := 3; { OS/2 uses RGBTRIPLE colormap }
  309. TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP_OS2_MAPPED, int (biWidth), int(biHeight));
  310. end;
  311. 24: { RGB image }
  312. TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP_OS2, int (biWidth), int(biHeight));
  313. else
  314. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
  315. end;
  316. if (biPlanes <> 1) then
  317. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADPLANES);
  318. end;
  319. 40,
  320. 64:begin
  321. { Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) }
  322. { or OS/2 2.x header, which has additional fields that we ignore }
  323. biWidth := {GET_4B(bmpinfoheader,4);}
  324. ( INT32(UCH(bmpinfoheader[4])) +
  325. ((INT32(UCH(bmpinfoheader[4+1])) shl 8)) +
  326. ((INT32(UCH(bmpinfoheader[4+2])) shl 16)) +
  327. ((INT32(UCH(bmpinfoheader[4+3])) shl 24)));
  328. biHeight := {GET_4B(bmpinfoheader,8);}
  329. ( INT32(UCH(bmpinfoheader[8])) +
  330. ((INT32(UCH(bmpinfoheader[8+1])) shl 8)) +
  331. ((INT32(UCH(bmpinfoheader[8+2])) shl 16)) +
  332. ((INT32(UCH(bmpinfoheader[8+3])) shl 24)));
  333. biPlanes := {GET_2B(bmpinfoheader,12);}
  334. ( uInt(UCH(bmpinfoheader[12])) +
  335. (uInt(UCH(bmpinfoheader[12+1])) shl 8) );
  336. source^.bits_per_pixel := {int (GET_2B(bmpinfoheader,14));}
  337. int( uInt(UCH(bmpinfoheader[14])) +
  338. ( uInt(UCH(bmpinfoheader[14+1])) shl 8) );
  339. biCompression := {GET_4B(bmpinfoheader,16);}
  340. ( INT32(UCH(bmpinfoheader[16])) +
  341. ((INT32(UCH(bmpinfoheader[16+1])) shl 8)) +
  342. ((INT32(UCH(bmpinfoheader[16+2])) shl 16)) +
  343. ((INT32(UCH(bmpinfoheader[16+3])) shl 24)));
  344. biXPelsPerMeter := {GET_4B(bmpinfoheader,24);}
  345. ( INT32(UCH(bmpinfoheader[24])) +
  346. ((INT32(UCH(bmpinfoheader[24+1])) shl 8)) +
  347. ((INT32(UCH(bmpinfoheader[24+2])) shl 16)) +
  348. ((INT32(UCH(bmpinfoheader[24+3])) shl 24)));
  349. biYPelsPerMeter := {GET_4B(bmpinfoheader,28);}
  350. ( INT32(UCH(bmpinfoheader[28])) +
  351. ((INT32(UCH(bmpinfoheader[28+1])) shl 8)) +
  352. ((INT32(UCH(bmpinfoheader[28+2])) shl 16)) +
  353. ((INT32(UCH(bmpinfoheader[28+3])) shl 24)));
  354. biClrUsed := {GET_4B(bmpinfoheader,32);}
  355. ( INT32(UCH(bmpinfoheader[32])) +
  356. ((INT32(UCH(bmpinfoheader[32+1])) shl 8)) +
  357. ((INT32(UCH(bmpinfoheader[32+2])) shl 16)) +
  358. ((INT32(UCH(bmpinfoheader[32+3])) shl 24)));
  359. { biSizeImage, biClrImportant fields are ignored }
  360. case (source^.bits_per_pixel) of
  361. 8: begin { colormapped image }
  362. mapentrysize := 4; { Windows uses RGBQUAD colormap }
  363. TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP_MAPPED, int (biWidth), int (biHeight));
  364. end;
  365. 24: { RGB image }
  366. TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP, int (biWidth), int (biHeight));
  367. else
  368. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
  369. end;
  370. if (biPlanes <> 1) then
  371. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADPLANES);
  372. if (biCompression <> 0) then
  373. ERREXIT(j_common_ptr(cinfo), JERR_BMP_COMPRESSED);
  374. if (biXPelsPerMeter > 0) and (biYPelsPerMeter > 0) then
  375. begin
  376. { Set JFIF density parameters from the BMP data }
  377. cinfo^.X_density := UINT16 (biXPelsPerMeter div 100); { 100 cm per meter }
  378. cinfo^.Y_density := UINT16 (biYPelsPerMeter div 100);
  379. cinfo^.density_unit := 2; { dots/cm }
  380. end;
  381. end;
  382. else
  383. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADHEADER);
  384. end;
  385. { Compute distance to bitmap data --- will adjust for colormap below }
  386. bPad := bfOffBits - (headerSize + 14);
  387. { Read the colormap, if any }
  388. if (mapentrysize > 0) then
  389. begin
  390. if (biClrUsed <= 0) then
  391. biClrUsed := 256 { assume it's 256 }
  392. else
  393. if (biClrUsed > 256) then
  394. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADCMAP);
  395. { Allocate space to store the colormap }
  396. source^.colormap := cinfo^.mem^.alloc_sarray(
  397. j_common_ptr (cinfo), JPOOL_IMAGE,
  398. JDIMENSION (biClrUsed), JDIMENSION (3));
  399. { and read it from the file }
  400. read_colormap(source, int (biClrUsed), mapentrysize);
  401. { account for size of colormap }
  402. Dec(bPad, biClrUsed * mapentrysize);
  403. end;
  404. { Skip any remaining pad bytes }
  405. if (bPad < 0) then { incorrect bfOffBits value? }
  406. ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADHEADER);
  407. while (bPad > 0) do
  408. begin
  409. Dec(bPad);
  410. {void} read_byte(source);
  411. end;
  412. { Compute row width in file, including padding to 4-byte boundary }
  413. if (source^.bits_per_pixel = 24) then
  414. row_width := JDIMENSION (biWidth * 3)
  415. else
  416. row_width := JDIMENSION (biWidth);
  417. while ((row_width and 3) <> 0) do
  418. Inc(row_width);
  419. source^.row_width := row_width;
  420. { Allocate space for inversion array, prepare for preload pass }
  421. source^.whole_image := cinfo^.mem^.request_virt_sarray(
  422. j_common_ptr (cinfo), JPOOL_IMAGE, FALSE,
  423. row_width, JDIMENSION (biHeight), JDIMENSION (1));
  424. source^.pub.get_pixel_rows := preload_image;
  425. if (cinfo^.progress <> NIL) then
  426. begin
  427. progress := cd_progress_ptr (cinfo^.progress);
  428. Inc(progress^.total_extra_passes); { count file input as separate pass }
  429. end;
  430. { Allocate one-row buffer for returned data }
  431. source^.pub.buffer := cinfo^.mem^.alloc_sarray(
  432. j_common_ptr (cinfo), JPOOL_IMAGE,
  433. JDIMENSION (biWidth * 3), JDIMENSION (1) );
  434. source^.pub.buffer_height := 1;
  435. cinfo^.in_color_space := JCS_RGB;
  436. cinfo^.input_components := 3;
  437. cinfo^.data_precision := 8;
  438. cinfo^.image_width := JDIMENSION (biWidth);
  439. cinfo^.image_height := JDIMENSION (biHeight);
  440. end;
  441. { Finish up at the end of the file. }
  442. {METHODDEF}
  443. procedure finish_input_bmp (cinfo : j_compress_ptr;
  444. sinfo : cjpeg_source_ptr); far;
  445. begin
  446. { no work }
  447. end;
  448. { The module selection routine for BMP format input. }
  449. {GLOBAL}
  450. function jinit_read_bmp (cinfo : j_compress_ptr) : cjpeg_source_ptr;
  451. var
  452. source : bmp_source_ptr;
  453. begin
  454. { Create module interface object }
  455. source := bmp_source_ptr (
  456. cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
  457. SIZEOF(bmp_source_struct)) );
  458. source^.cinfo := cinfo; { make back link for subroutines }
  459. { Fill in method ptrs, except get_pixel_rows which start_input sets }
  460. source^.pub.start_input := start_input_bmp;
  461. source^.pub.finish_input := finish_input_bmp;
  462. jinit_read_bmp := cjpeg_source_ptr (source);
  463. end;
  464. end.