📄 rdbmp.pas
字号:
{ Read the file header; return image size and component count. }
{METHODDEF}
procedure start_input_bmp (cinfo : j_compress_ptr;
sinfo : cjpeg_source_ptr); far;
var
source : bmp_source_ptr;
bmpfileheader : packed array[0..14-1] of U_CHAR;
bmpinfoheader : packed array[0..64-1] of U_CHAR;
bfOffBits : INT32 ;
headerSize : INT32;
biWidth : INT32; { initialize to avoid compiler warning }
biHeight : INT32;
biPlanes : uInt;
biCompression : INT32;
biXPelsPerMeter,biYPelsPerMeter : INT32;
biClrUsed : INT32;
mapentrysize : int;
bPad : INT32;
row_width : JDIMENSION;
var
progress : cd_progress_ptr;
begin
source := bmp_source_ptr (sinfo);
biWidth := 0; { initialize to avoid compiler warning }
biHeight := 0;
biClrUsed := 0;
mapentrysize := 0; { 0 indicates no colormap }
{ Read and verify the bitmap file header }
if JFREAD(source^.pub.input_file^, @bmpfileheader, 14) <> size_t (14) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
{ GET_2B(bmpfileheader, 0) }
if (uInt(UCH(bmpfileheader[0]) +
(uInt(UCH(bmpfileheader[0+1])) shl 8)) <> $4D42) then { 'BM' }
ERREXIT(j_common_ptr(cinfo), JERR_BMP_NOT);
bfOffBits := {INT32 ( GET_4B(bmpfileheader,10) );}
INT32( INT32(UCH(bmpfileheader[10])) +
((INT32(UCH(bmpfileheader[10+1])) shl 8)) +
((INT32(UCH(bmpfileheader[10+2])) shl 16)) +
((INT32(UCH(bmpfileheader[10+3])) shl 24)));
{ We ignore the remaining fileheader fields }
{ The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which. }
if JFREAD(source^.pub.input_file^, @bmpinfoheader, 4) <> size_t(4) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
headerSize := {INT32 (GET_4B(bmpinfoheader,0));}
INT32( INT32(UCH(bmpinfoheader[0])) +
((INT32(UCH(bmpinfoheader[0+1])) shl 8)) +
((INT32(UCH(bmpinfoheader[0+2])) shl 16)) +
((INT32(UCH(bmpinfoheader[0+3])) shl 24)));
if (headerSize < 12) or (headerSize > 64) then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADHEADER);
if JFREAD(source^.pub.input_file^,@bmpinfoheader[4],headerSize-4) <>
size_t (headerSize-4) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
case int(headerSize) of
12:begin
{ Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) }
biWidth := {INT32 (GET_2B(bmpinfoheader,4));}
INT32( uInt(UCH(bmpinfoheader[4])) +
(uInt(UCH(bmpinfoheader[4+1])) shl 8) );
biHeight := {INT32 (GET_2B(bmpinfoheader,6));}
INT32( uInt(UCH(bmpinfoheader[6])) +
(uInt(UCH(bmpinfoheader[6+1])) shl 8) );
biPlanes := {GET_2B(bmpinfoheader,8);}
uInt(UCH(bmpinfoheader[8])) +
(uInt(UCH(bmpinfoheader[8+1])) shl 8);
source^.bits_per_pixel := {int (GET_2B(bmpinfoheader,10));}
int( uInt(UCH(bmpinfoheader[10])) +
(uInt(UCH(bmpinfoheader[10+1])) shl 8));
case (source^.bits_per_pixel) of
8: begin { colormapped image }
mapentrysize := 3; { OS/2 uses RGBTRIPLE colormap }
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP_OS2_MAPPED, int (biWidth), int(biHeight));
end;
24: { RGB image }
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP_OS2, int (biWidth), int(biHeight));
else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
end;
if (biPlanes <> 1) then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADPLANES);
end;
40,
64:begin
{ Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) }
{ or OS/2 2.x header, which has additional fields that we ignore }
biWidth := {GET_4B(bmpinfoheader,4);}
( INT32(UCH(bmpinfoheader[4])) +
((INT32(UCH(bmpinfoheader[4+1])) shl 8)) +
((INT32(UCH(bmpinfoheader[4+2])) shl 16)) +
((INT32(UCH(bmpinfoheader[4+3])) shl 24)));
biHeight := {GET_4B(bmpinfoheader,8);}
( INT32(UCH(bmpinfoheader[8])) +
((INT32(UCH(bmpinfoheader[8+1])) shl 8)) +
((INT32(UCH(bmpinfoheader[8+2])) shl 16)) +
((INT32(UCH(bmpinfoheader[8+3])) shl 24)));
biPlanes := {GET_2B(bmpinfoheader,12);}
( uInt(UCH(bmpinfoheader[12])) +
(uInt(UCH(bmpinfoheader[12+1])) shl 8) );
source^.bits_per_pixel := {int (GET_2B(bmpinfoheader,14));}
int( uInt(UCH(bmpinfoheader[14])) +
( uInt(UCH(bmpinfoheader[14+1])) shl 8) );
biCompression := {GET_4B(bmpinfoheader,16);}
( INT32(UCH(bmpinfoheader[16])) +
((INT32(UCH(bmpinfoheader[16+1])) shl 8)) +
((INT32(UCH(bmpinfoheader[16+2])) shl 16)) +
((INT32(UCH(bmpinfoheader[16+3])) shl 24)));
biXPelsPerMeter := {GET_4B(bmpinfoheader,24);}
( INT32(UCH(bmpinfoheader[24])) +
((INT32(UCH(bmpinfoheader[24+1])) shl 8)) +
((INT32(UCH(bmpinfoheader[24+2])) shl 16)) +
((INT32(UCH(bmpinfoheader[24+3])) shl 24)));
biYPelsPerMeter := {GET_4B(bmpinfoheader,28);}
( INT32(UCH(bmpinfoheader[28])) +
((INT32(UCH(bmpinfoheader[28+1])) shl 8)) +
((INT32(UCH(bmpinfoheader[28+2])) shl 16)) +
((INT32(UCH(bmpinfoheader[28+3])) shl 24)));
biClrUsed := {GET_4B(bmpinfoheader,32);}
( INT32(UCH(bmpinfoheader[32])) +
((INT32(UCH(bmpinfoheader[32+1])) shl 8)) +
((INT32(UCH(bmpinfoheader[32+2])) shl 16)) +
((INT32(UCH(bmpinfoheader[32+3])) shl 24)));
{ biSizeImage, biClrImportant fields are ignored }
case (source^.bits_per_pixel) of
8: begin { colormapped image }
mapentrysize := 4; { Windows uses RGBQUAD colormap }
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP_MAPPED, int (biWidth), int (biHeight));
end;
24: { RGB image }
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_BMP, int (biWidth), int (biHeight));
else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
end;
if (biPlanes <> 1) then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADPLANES);
if (biCompression <> 0) then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_COMPRESSED);
if (biXPelsPerMeter > 0) and (biYPelsPerMeter > 0) then
begin
{ Set JFIF density parameters from the BMP data }
cinfo^.X_density := UINT16 (biXPelsPerMeter div 100); { 100 cm per meter }
cinfo^.Y_density := UINT16 (biYPelsPerMeter div 100);
cinfo^.density_unit := 2; { dots/cm }
end;
end;
else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADHEADER);
end;
{ Compute distance to bitmap data --- will adjust for colormap below }
bPad := bfOffBits - (headerSize + 14);
{ Read the colormap, if any }
if (mapentrysize > 0) then
begin
if (biClrUsed <= 0) then
biClrUsed := 256 { assume it's 256 }
else
if (biClrUsed > 256) then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADCMAP);
{ Allocate space to store the colormap }
source^.colormap := cinfo^.mem^.alloc_sarray(
j_common_ptr (cinfo), JPOOL_IMAGE,
JDIMENSION (biClrUsed), JDIMENSION (3));
{ and read it from the file }
read_colormap(source, int (biClrUsed), mapentrysize);
{ account for size of colormap }
Dec(bPad, biClrUsed * mapentrysize);
end;
{ Skip any remaining pad bytes }
if (bPad < 0) then { incorrect bfOffBits value? }
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADHEADER);
while (bPad > 0) do
begin
Dec(bPad);
{void} read_byte(source);
end;
{ Compute row width in file, including padding to 4-byte boundary }
if (source^.bits_per_pixel = 24) then
row_width := JDIMENSION (biWidth * 3)
else
row_width := JDIMENSION (biWidth);
while ((row_width and 3) <> 0) do
Inc(row_width);
source^.row_width := row_width;
{ Allocate space for inversion array, prepare for preload pass }
source^.whole_image := cinfo^.mem^.request_virt_sarray(
j_common_ptr (cinfo), JPOOL_IMAGE, FALSE,
row_width, JDIMENSION (biHeight), JDIMENSION (1));
source^.pub.get_pixel_rows := preload_image;
if (cinfo^.progress <> NIL) then
begin
progress := cd_progress_ptr (cinfo^.progress);
Inc(progress^.total_extra_passes); { count file input as separate pass }
end;
{ Allocate one-row buffer for returned data }
source^.pub.buffer := cinfo^.mem^.alloc_sarray(
j_common_ptr (cinfo), JPOOL_IMAGE,
JDIMENSION (biWidth * 3), JDIMENSION (1) );
source^.pub.buffer_height := 1;
cinfo^.in_color_space := JCS_RGB;
cinfo^.input_components := 3;
cinfo^.data_precision := 8;
cinfo^.image_width := JDIMENSION (biWidth);
cinfo^.image_height := JDIMENSION (biHeight);
end;
{ Finish up at the end of the file. }
{METHODDEF}
procedure finish_input_bmp (cinfo : j_compress_ptr;
sinfo : cjpeg_source_ptr); far;
begin
{ no work }
end;
{ The module selection routine for BMP format input. }
{GLOBAL}
function jinit_read_bmp (cinfo : j_compress_ptr) : cjpeg_source_ptr;
var
source : bmp_source_ptr;
begin
{ Create module interface object }
source := bmp_source_ptr (
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
SIZEOF(bmp_source_struct)) );
source^.cinfo := cinfo; { make back link for subroutines }
{ Fill in method ptrs, except get_pixel_rows which start_input sets }
source^.pub.start_input := start_input_bmp;
source^.pub.finish_input := finish_input_bmp;
jinit_read_bmp := cjpeg_source_ptr (source);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -