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

📄 rdbmp.pas

📁 用pascal寫的jpeg codec, 測試過的
💻 PAS
📖 第 1 页 / 共 2 页
字号:
Unit RdBmp;

{ rdbmp.c

  Copyright (C) 1994-1996, Thomas G. Lane.
  This file is part of the Independent JPEG Group's software.
  For conditions of distribution and use, see the accompanying README file.

  This file contains routines to read input images in Microsoft "BMP"
  format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
  Currently, only 8-bit and 24-bit images are supported, not 1-bit or
  4-bit (feeding such low-depth images into JPEG would be silly anyway).
  Also, we don't support RLE-compressed files.

  These routines may need modification for non-Unix environments or
  specialized applications.  As they stand, they assume input from
  an ordinary stdio stream.  They further assume that reading begins
  at the start of the file; start_input may need work if the
  user interface has already read some data (e.g., to determine that
  the file is indeed BMP format).

  This code contributed by James Arthur Boucher. }

interface

{$I jconfig.inc}

uses
  jmorecfg,
  jpeglib,
  jinclude,
  jdeferr,
  jerror,
  cdjpeg;		{ Common decls for cjpeg/djpeg applications }

{ The module selection routine for BMP format input. }

{GLOBAL}
function jinit_read_bmp (cinfo : j_compress_ptr) : cjpeg_source_ptr;

implementation

{ Macros to deal with unsigned chars as efficiently as compiler allows }

{$define HAVE_UNSIGNED_CHAR}
{$ifdef HAVE_UNSIGNED_CHAR}
type
  U_CHAR =  byte;
  UCH = int;
{$else} { !HAVE_UNSIGNED_CHAR }
  {$ifdef CHAR_IS_UNSIGNED}
  type
    U_CHAR = char;
    UCH = int;
  {$else}
  type
    U_CHAR = char;
    UCH = int(x) and $FF
  {$endif}
{$endif} { HAVE_UNSIGNED_CHAR }


{ Private version of data source object }

type
  bmp_source_ptr = ^bmp_source_struct;
  bmp_source_struct = record
    pub : cjpeg_source_struct; { public fields }

    cinfo : j_compress_ptr;		{ back link saves passing separate parm }

    colormap : JSAMPARRAY;		{ BMP colormap (converted to my format) }

    whole_image : jvirt_sarray_ptr;	{ Needed to reverse row order }
    source_row : JDIMENSION;	{ Current source row number }
    row_width : JDIMENSION;		{ Physical width of scanlines in file }

    bits_per_pixel : int;		{ remembers 8- or 24-bit format }
  end; { bmp_source_struct }


{LOCAL}
function read_byte (sinfo : bmp_source_ptr) : int;
{ Read next byte from BMP file }
var
  {register} infile : FILEptr;
  {register} c : byte;
begin
  infile := sinfo^.pub.input_file;
  if JFREAD(infile^, @c, 1) <> size_t(1) then
    ERREXIT(j_common_ptr(sinfo^.cinfo), JERR_INPUT_EOF);
  read_byte  := c;
end;


{LOCAL}
procedure read_colormap (sinfo : bmp_source_ptr;
                         cmaplen : int;
                         mapentrysize : int);
{ Read the colormap from a BMP file }
var
  i : int;
begin
  case (mapentrysize) of
  3:{ BGR format (occurs in OS/2 files) }
    for i := 0 to pred(cmaplen) do
    begin
      sinfo^.colormap^[2]^[i] := JSAMPLE (read_byte(sinfo));
      sinfo^.colormap^[1]^[i] := JSAMPLE (read_byte(sinfo));
      sinfo^.colormap^[0]^[i] := JSAMPLE (read_byte(sinfo));
    end;
  4:{ BGR0 format (occurs in MS Windows files) }
    for i := 0 to pred(cmaplen) do
    begin
      sinfo^.colormap^[2]^[i] := JSAMPLE (read_byte(sinfo));
      sinfo^.colormap^[1]^[i] := JSAMPLE (read_byte(sinfo));
      sinfo^.colormap^[0]^[i] := JSAMPLE (read_byte(sinfo));
      {void} read_byte(sinfo);
    end;
  else
    ERREXIT(j_common_ptr(sinfo^.cinfo), JERR_BMP_BADCMAP);
  end;
end;


{ Read one row of pixels.
  The image has been read into the whole_image 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. }

{METHODDEF}
function  get_8bit_row (cinfo : j_compress_ptr;
                        sinfo : cjpeg_source_ptr) : JDIMENSION; far;
{ This version is for reading 8-bit colormap indexes }
var
  source : bmp_source_ptr;
  {register} colormap : JSAMPARRAY;
  image_ptr : JSAMPARRAY;
  {register} t : int;
  {register} inptr, outptr : JSAMPLE_PTR;
  {register} col : JDIMENSION;
begin
  source := bmp_source_ptr (sinfo);
  colormap := source^.colormap;
  { Fetch next row from virtual array }
  Dec(source^.source_row);
  image_ptr := cinfo^.mem^.access_virt_sarray(
     j_common_ptr (cinfo), source^.whole_image,
     source^.source_row, JDIMENSION (1), FALSE);

  { Expand the colormap indexes to real data }
  inptr := JSAMPLE_PTR(image_ptr^[0]);
  outptr := JSAMPLE_PTR(source^.pub.buffer^[0]);
  for col := pred(cinfo^.image_width) downto 0 do
  begin
    t := GETJSAMPLE(inptr^);
    Inc(inptr);
    outptr^ := colormap^[0]^[t];       { can omit GETJSAMPLE() safely }
    Inc(outptr);
    outptr^ := colormap^[1]^[t];
    Inc(outptr);
    outptr^ := colormap^[2]^[t];
    Inc(outptr);
  end;

  get_8bit_row  := 1;
end;


{METHODDEF}
function get_24bit_row (cinfo : j_compress_ptr;
                        sinfo : cjpeg_source_ptr) : JDIMENSION; far;
{ This version is for reading 24-bit pixels }
var
  source : bmp_source_ptr;
  image_ptr : JSAMPARRAY;
  {register} inptr : JSAMPLE_PTR;
  {register} outptr : JSAMPROW;
  {register} col : JDIMENSION;
begin
  source := bmp_source_ptr (sinfo);
  { Fetch next row from virtual array }
  Dec(source^.source_row);
  image_ptr := cinfo^.mem^.access_virt_sarray (
     j_common_ptr (cinfo), source^.whole_image,
     source^.source_row, JDIMENSION (1), FALSE);

  { Transfer data.  Note source values are in BGR order
    (even though Microsoft's own documents say the opposite). }

  inptr := JSAMPLE_PTR(image_ptr^[0]);
  outptr := source^.pub.buffer^[0];
  for col := pred(cinfo^.image_width) downto 0 do
  begin
    outptr^[2] := inptr^;	{ can omit GETJSAMPLE() safely }
    Inc(inptr);
    outptr^[1] := inptr^;
    Inc(inptr);
    outptr^[0] := inptr^;
    Inc(inptr);
    Inc(JSAMPLE_PTR(outptr), 3);
  end;

  get_24bit_row := 1;
end;


{ This method loads the image into whole_image during the first call on
  get_pixel_rows.  The get_pixel_rows pointer is then adjusted to call
  get_8bit_row or get_24bit_row on subsequent calls. }

{METHODDEF}
function preload_image (cinfo : j_compress_ptr;
                        sinfo : cjpeg_source_ptr) : JDIMENSION; far;
var
  source : bmp_source_ptr;
  {register} infile : FILEptr;
  {register} c : int;
  {register} out_ptr : JSAMPLE_PTR;
  image_ptr : JSAMPARRAY;
  row, col : JDIMENSION;
  progress : cd_progress_ptr;
begin
  source := bmp_source_ptr (sinfo);
  infile := source^.pub.input_file;
  progress := cd_progress_ptr (cinfo^.progress);

  { Read the data into a virtual array in input-file row order. }
  for row := 0 to pred(cinfo^.image_height) do
  begin
    if (progress <> NIL) then
    begin
      progress^.pub.pass_counter := long (row);
      progress^.pub.pass_limit := long (cinfo^.image_height);
      progress^.pub.progress_monitor (j_common_ptr (cinfo));
    end;
    image_ptr := cinfo^.mem^.access_virt_sarray (
       j_common_ptr (cinfo), source^.whole_image,
       row, JDIMENSION (1), TRUE);
    out_ptr := JSAMPLE_PTR(image_ptr^[0]);
    {$IFDEF Original}
    for col := pred(source^.row_width) downto 0 do
    begin
      { inline copy of read_byte() for speed }
      c := getc(infile);
      if (c = EOF) then
	ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
      out_ptr^ := JSAMPLE (c);
      Inc(out_ptr);
    end;
    {$ELSE}
    if JFREAD(infile^, out_ptr, source^.row_width) <>
      size_t(source^.row_width) then
	ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EOF);
    {$ENDIF}
  end;
  if (progress <> NIL) then
    Inc(progress^.completed_extra_passes);

  { Set up to read from the virtual array in top-to-bottom order }
  case (source^.bits_per_pixel) of
   8: source^.pub.get_pixel_rows := get_8bit_row;
  24: source^.pub.get_pixel_rows := get_24bit_row;
  else
    ERREXIT(j_common_ptr(cinfo), JERR_BMP_BADDEPTH);
  end;
  source^.source_row := cinfo^.image_height;

  { And read the first row }
  preload_image := source^.pub.get_pixel_rows (cinfo, sinfo);
end;


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -