📄 pasjpeg.pas
字号:
a := 0;
end;
i := 256;
end;
{pad colormap with zeros to ensure specified number of colormap entries}
if i > cmap_entries then
ERREXIT1(j_common_ptr(cinfo), JERR_TOO_MANY_COLORS, i);
while i < cmap_entries do begin
with output_ext_color_map[i] do begin
b := 0;
g := 0;
r := 0;
a := 0;
end;
Inc(i);
end;
if dest^.outfile.Write(output_ext_color_map, cmap_entries*4)
<> cmap_entries*4 then
ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);
end;
dest^.row_offset := bmpfileheader.bfSize;
end;
procedure write_bmp_pixelrow (cinfo : j_decompress_ptr;
dest : bmp_dest_ptr;
rows_supplied : JDIMENSION);
var
image_ptr : JSAMPARRAY;
inptr, outptr : JSAMPLE_PTR;
BGR : BGRptr;
col,row : JDIMENSION;
pad : int;
begin
if dest^.inmemory then begin
row := dest^.cur_output_row;
Inc(dest^.cur_output_row);
end else begin
row := 0;
Dec(dest^.row_offset, dest^.row_width);
end;
image_ptr := cinfo^.mem^.access_virt_sarray ( j_common_ptr(cinfo),
dest^.image_buffer, row, JDIMENSION (1), TRUE);
inptr := JSAMPLE_PTR(dest^.buffer^[0]);
if not dest^.grayscale then begin
BGR := BGRptr(image_ptr^[0]);
for col := pred(cinfo^.output_width) downto 0 do begin
BGR^.r := inptr^;
Inc(inptr);
BGR^.g := inptr^;
Inc(inptr);
BGR^.b := inptr^;
Inc(inptr);
Inc(BGR);
end;
outptr := JSAMPLE_PTR(BGR);
end else begin
outptr := JSAMPLE_PTR(image_ptr^[0]);
for col := pred(cinfo^.output_width) downto 0 do begin
outptr^ := inptr^;
Inc(outptr);
Inc(inptr);
end;
end;
{zero out the pad bytes}
pad := dest^.pad_bytes;
while (pad > 0) do begin
Dec(pad);
outptr^ := 0;
Inc(outptr);
end;
if not dest^.inmemory then begin
{store row in output stream}
image_ptr := cinfo^.mem^.access_virt_sarray ( j_common_ptr(cinfo),
dest^.image_buffer, 0, JDIMENSION(1), FALSE);
outptr := JSAMPLE_PTR(image_ptr^[0]);
if dest^.outfile.Seek(dest^.row_offset, 0) <> dest^.row_offset then
ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);
if dest^.outfile.Write(outptr^, dest^.row_width) <> dest^.row_width then
ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);
end;
end;
procedure write_bmp_image (cinfo : j_decompress_ptr;
dest : bmp_dest_ptr);
var
row, col : JDIMENSION;
image_ptr : JSAMPARRAY;
data_ptr : JSAMPLE_PTR;
begin
if dest^.inmemory then {write the image data from our virtual array}
for row := cinfo^.output_height downto 1 do begin
image_ptr := cinfo^.mem^.access_virt_sarray( j_common_ptr(cinfo),
dest^.image_buffer, row-1, JDIMENSION(1), FALSE);
data_ptr := JSAMPLE_PTR(image_ptr^[0]);
{Nomssi - This won't work for 12bit samples}
if dest^.outfile.Write(data_ptr^, dest^.row_width) <> dest^.row_width then
ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);
end;
end;
function jinit_write_bmp (cinfo : j_decompress_ptr;
outfile : TStream;
inmemory : boolean) : bmp_dest_ptr;
var
dest : bmp_dest_ptr;
begin
dest := bmp_dest_ptr (
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
SIZEOF(bmp_dest_struct)) );
dest^.outfile := outfile;
dest^.inmemory := inmemory;
{image info}
jpeg_calc_output_dimensions(cinfo);
dest^.data_width := cinfo^.output_width * cinfo^.output_components;
dest^.row_width := dest^.data_width;
while ((dest^.row_width and 3) <> 0) do
Inc(dest^.row_width);
dest^.pad_bytes := int(dest^.row_width-dest^.data_width);
if (cinfo^.out_color_space = JCS_GRAYSCALE) then
dest^.grayscale := True
else if (cinfo^.out_color_space = JCS_RGB) then
if (cinfo^.quantize_colors) then
dest^.grayscale := True
else
dest^.grayscale := False
else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_COLORSPACE);
{decompress buffer}
dest^.buffer := cinfo^.mem^.alloc_sarray
(j_common_ptr(cinfo), JPOOL_IMAGE, dest^.row_width, JDIMENSION (1));
dest^.buffer_height := 1;
{image buffer}
if inmemory then
dest^.image_buffer_height := cinfo^.output_height
else
dest^.image_buffer_height := 1;
dest^.image_buffer := cinfo^.mem^.request_virt_sarray (
j_common_ptr(cinfo), JPOOL_IMAGE, FALSE, dest^.row_width,
dest^.image_buffer_height, JDIMENSION (1) );
dest^.cur_output_row := 0;
{result}
jinit_write_bmp := dest;
end;
{ ------------------------------------------------------------------------ }
{ Bitmap reading routines }
{ for reference: RDBMP.PAS in PASJPG10 library }
{ ------------------------------------------------------------------------ }
type
bmp_source_ptr = ^bmp_source_struct;
bmp_source_struct = record
infile : TStream; {stream to read from}
inmemory : boolean; {keep whole image in memory}
{image info}
bits_per_pixel : INT; {bit depth}
colormap : JSAMPARRAY; {BMP colormap (converted to my format)}
row_width : JDIMENSION; {physical width of one row in the BMP file}
{pixelrow buffer}
buffer : JSAMPARRAY; {pixelrow buffer}
buffer_height : JDIMENSION; {normally, we'll use 1}
{image buffer}
image_buffer : jvirt_sarray_ptr; {needed to reverse order BMP<>JPG}
image_buffer_height : JDIMENSION; {image_height}
cur_input_row : JDIMENSION; {current source row number}
row_offset : INT32; {position of next row to read from BMP}
end;
procedure read_bmp_header (cinfo : j_compress_ptr;
source : bmp_source_ptr);
var
bmpfileheader : TBitmapFileHeader;
bmpcoreheader : TBitmapCoreHeader;
bmpinfoheader : TBitmapInfoHeader;
i, cmap_entrysize : INT;
function read_byte: INT;
{Read next byte from BMP file}
var
c: byte;
begin
if source^.infile.Read(c, 1) <> size_t(1) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
read_byte := c;
end;
begin
cmap_entrysize := 0; { 0 indicates no colormap }
{bitmap file header:}
if source^.infile.Read(bmpfileheader, SizeOf(bmpfileheader))
<> size_t(SizeOf(bmpfileheader)) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
if bmpfileheader.bfType <> $4D42 then {'BM'}
ERREXIT(j_common_ptr(cinfo), JERR_BMP_NOT);
{bitmap 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 source^.infile.Read(bmpinfoheader, SizeOf(INT32)) <> size_t(SizeOf(INT32)) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
{OS/2 1.x format}
if bmpinfoheader.biSize = SizeOf(TBitmapCoreHeader) then begin
bmpcoreheader.bcSize := bmpinfoheader.biSize;
if source^.infile.Read(bmpcoreheader.bcWidth, bmpcoreheader.bcSize-SizeOf(INT32))
<> size_t (bmpcoreheader.bcSize-SizeOf(INT32)) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
bmpinfoheader.biWidth := bmpcoreheader.bcWidth;
bmpinfoheader.biHeight := bmpcoreheader.bcHeight;
bmpinfoheader.biPlanes := bmpcoreheader.bcPlanes;
bmpinfoheader.biBitCount := bmpcoreheader.bcBitCount;
bmpinfoheader.biClrUsed := 0;
source^.bits_per_pixel := bmpinfoheader.biBitCount;
case source^.bits_per_pixel of
8: begin {colormapped image}
cmap_entrysize := 3; {OS/2 uses RGBTRIPLE colormap}
TRACEMS2( j_common_ptr(cinfo), 1, JTRC_BMP_OS2_MAPPED,
int (bmpinfoheader.biWidth), int(bmpinfoheader.biHeight));
end;
24: { RGB image }
TRACEMS2( j_common_ptr(cinfo), 1, JTRC_BMP_OS2,
int (bmpinfoheader.biWidth), int(bmpinfoheader.biHeight) );
else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
end;
if bmpinfoheader.biPlanes <> 1 then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADPLANES);
end else
{Windows 3.x or OS/2 2.x header, which has additional fields that we ignore }
if (bmpinfoheader.biSize = SizeOf(TBitmapInfoHeader)) or
(bmpinfoheader.biSize = 64) then
begin
if source^.infile.Read(bmpinfoheader.biWidth, SizeOf(bmpinfoheader)-SizeOf(INT32))
<> size_t (SizeOf(bmpinfoheader)-SizeOf(INT32)) then
ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
if bmpinfoheader.biSize = 64 then
source^.infile.Seek(64-SizeOf(TBitmapInfoHeader), 1);
source^.bits_per_pixel := bmpinfoheader.biBitCount;
case source^.bits_per_pixel of
8: begin {colormapped image}
cmap_entrysize := 4; {Windows uses RGBQUAD colormap}
TRACEMS2( j_common_ptr(cinfo), 1, JTRC_BMP_MAPPED,
int (bmpinfoheader.biWidth), int(bmpinfoheader.biHeight) );
end;
24: {RGB image}
TRACEMS2( j_common_ptr(cinfo), 1, JTRC_BMP,
int (bmpinfoheader.biWidth), int(bmpinfoheader.biHeight) );
else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
end;
if (bmpinfoheader.biPlanes <> 1) then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADPLANES);
if (bmpinfoheader.biCompression <> 0) then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_COMPRESSED);
if (bmpinfoheader.biXPelsPerMeter > 0) and (bmpinfoheader.biYPelsPerMeter > 0) then
begin
{Set JFIF density parameters from the BMP data}
cinfo^.X_density := bmpinfoheader.biXPelsPerMeter div 100; {100 cm per meter}
cinfo^.Y_density := bmpinfoheader.biYPelsPerMeter div 100;
cinfo^.density_unit := 2; { dots/cm }
end;
end else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADHEADER);
{colormap}
if cmap_entrysize > 0 then begin
if bmpinfoheader.biClrUsed <= 0 then
bmpinfoheader.biClrUsed := 256 {assume it's 256}
else
if bmpinfoheader.biClrUsed > 256 then
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADCMAP);
{allocate colormap}
source^.colormap := cinfo^.mem^.alloc_sarray( j_common_ptr (cinfo),
JPOOL_IMAGE, JDIMENSION(bmpinfoheader.biClrUsed), JDIMENSION (3));
{read it}
case cmap_entrysize of
3: {BGR format (occurs in OS/2 files)}
for i := 0 to pred(bmpinfoheader.biClrUsed) do begin
source^.colormap^[2]^[i] := JSAMPLE (read_byte);
source^.colormap^[1]^[i] := JSAMPLE (read_byte);
source^.colormap^[0]^[i] := JSAMPLE (read_byte);
end;
4: {BGR0 format (occurs in MS Windows files)}
for i := 0 to pred(bmpinfoheader.biClrUsed) do begin
source^.colormap^[2]^[i] := JSAMPLE (read_byte);
source^.colormap^[1]^[i] := JSAMPLE (read_byte);
source^.colormap^[0]^[i] := JSAMPLE (read_byte);
read_byte;
end;
else
ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADCMAP);
end;
end;
{initialize bmp_source_struc}
{row width, including padding to 4-byte boundary}
if source^.bits_per_pixel = 24 then
source^.row_width := JDIMENSION(bmpinfoheader.biWidth*3)
else
source^.row_width := JDIMENSION (bmpinfoheader.biWidth);
while ((source^.row_width and 3) <> 0) do
Inc(source^.row_width);
{allocate pixelrow buffer}
source^.buffer := cinfo^.mem^.alloc_sarray( j_common_ptr (cinfo),
JPOOL_IMAGE, JDIMENSION (bmpinfoheader.biWidth*3), JDIMENSION (1) );
source^.buffer_height := 1;
{allocate image buffer}
if source^.inmemory then begin
source^.image_buffer_height := bmpinfoheader.biHeight;
source^.cur_input_row := bmpinfoheader.biHeight;
end else begin
source^.image_buffer_height := 1;
source^.row_offset := bmpfileheader.bfSize;
end;
source^.image_buffer := cinfo^.mem^.request_virt_sarray (
j_common_ptr (cinfo), JPOOL_IMAGE, FALSE, source^.row_width,
JDIMENSION(source^.image_buffer_height), JDIMENSION (1) );
{set decompress parameters}
cinfo^.in_color_space := JCS_RGB;
cinfo^.input_components := 3;
cinfo^.data_precision := 8;
cinfo^.image_width := JDIMENSION (bmpinfoheader.biWidth);
cinfo^.image_height := JDIMENSION (bmpinfoheader.biHeight);
end;
function read_bmp_pixelrow (cinfo : j_compress_ptr;
source : bmp_source_ptr) : JDIMENSION;
{ Read one row of pixels:
the image has been read into the image_buffer array, but is otherwise
unprocessed. we must read it out in top-to-bottom row order, and if
it is an 8-bit image, we must expand colormapped pixels to 24bit format. }
var
col, row : JDIMENSION;
image_ptr : JSAMPARRAY;
inptr, outptr : JSAMPLE_PTR;
outptr24 : JSAMPROW;
t : INT;
begin
if source^.inmemory then begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -