⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pasjpeg.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 3 页
字号:
          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 + -