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

📄 rdbmp.pas

📁 用pascal寫的jpeg codec, 測試過的
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{ 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 + -