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

📄 wrbmp.pas

📁 用pascal寫的jpeg codec, 測試過的
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    else
    begin
      { Unquantized, full color RGB }
      bits_per_pixel := 24;
      cmap_entries := 0;
    end;
  end
  else
  begin
    { Grayscale output.  We need to fake a 256-entry colormap. }
    bits_per_pixel := 8;
    cmap_entries := 256;
  end;
  { File size }
  headersize := 14 + 12 + cmap_entries * 3; { Header and colormap }
  bfSize := headersize + INT32 (dest^.row_width) * INT32 (cinfo^.output_height);

  { Set unused fields of header to 0 }
  MEMZERO(@bmpfileheader, SIZEOF(bmpfileheader));
  MEMZERO(@bmpcoreheader, SIZEOF(bmpcoreheader));

  { Fill the file header }
  bmpfileheader[0] := $42;	{ first 2 bytes are ASCII 'B', 'M' }
  bmpfileheader[1] := $4D;
  {PUT_4B(bmpfileheader, 2, bfSize);} { bfSize }
	 bmpfileheader[2] := byte ((headersize) and $FF);
	 bmpfileheader[2+1] := byte (((headersize) shr 8) and $FF);
	 bmpfileheader[2+2] := byte (((headersize) shr 16) and $FF);
	 bmpfileheader[2+3] := byte (((headersize) shr 24) and $FF);
  { we leave bfReserved1 & bfReserved2 := 0 }
  {PUT_4B(bmpfileheader, 10, headersize);} { bfOffBits }
	 bmpfileheader[10] := byte ((headersize) and $FF);
	 bmpfileheader[10+1] := byte (((headersize) shr 8) and $FF);
	 bmpfileheader[10+2] := byte (((headersize) shr 16) and $FF);
	 bmpfileheader[10+3] := byte (((headersize) shr 24) and $FF);

  { Fill the info header (Microsoft calls this a BITMAPCOREHEADER) }
  {PUT_2B(bmpcoreheader, 0, 12);}	{ bcSize }
	 bmpcoreheader[0] := byte (12 and $FF);
	 bmpcoreheader[0+1] := byte ((12 shr 8) and $FF);
  {PUT_2B(bmpcoreheader, 4, cinfo^.output_width);} { bcWidth }
	 bmpcoreheader[4] := byte (cinfo^.output_width and $FF);
	 bmpcoreheader[4+1] := byte ((cinfo^.output_width shr 8) and $FF);
  {PUT_2B(bmpcoreheader, 6, cinfo^.output_height);} { bcHeight }
	 bmpcoreheader[6] := byte (cinfo^.output_height and $FF);
	 bmpcoreheader[6+1] := byte ((cinfo^.output_height shr 8) and $FF);
  {PUT_2B(bmpcoreheader, 8, 1);}	{ bcPlanes - must be 1 }
	 bmpcoreheader[8] := byte (1 and $FF);
	 bmpcoreheader[8+1] := byte ((1 shr 8) and $FF);
  {PUT_2B(bmpcoreheader, 10, bits_per_pixel);} { bcBitCount }
	 bmpcoreheader[10] := byte (bits_per_pixel and $FF);
	 bmpcoreheader[10+1] := byte ((bits_per_pixel shr 8) and $FF);

  if (JFWRITE(dest^.pub.output_file^, @bmpfileheader, 14) <> size_t (14)) then
    ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);
  if (JFWRITE(dest^.pub.output_file^, @bmpcoreheader, 12) <> size_t (12)) then
    ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE);

  if (cmap_entries > 0) then
    write_colormap(cinfo, dest, cmap_entries, 3);
end;


{ Write the colormap.
  Windows uses BGR0 map entries; OS/2 uses BGR entries. }

{LOCAL}
procedure write_colormap (cinfo : j_decompress_ptr;
                          dest : bmp_dest_ptr;
		          map_colors : int;
                          map_entry_size : int);
var
  colormap : JSAMPARRAY;
  num_colors : int;
  outfile : FILEptr;
  i : int;
var
  output_color_map : Array[0..255] of BGRtype;
  output_ext_color_map : Array[0..255] of record
                                            b,g,r,a : byte;
                                          end;
begin
  colormap := cinfo^.colormap;
  num_colors := cinfo^.actual_number_of_colors;
  outfile := dest^.pub.output_file;

  if (colormap <> NIL) then
  begin
    if (cinfo^.out_color_components = 3) then
    begin
      { Normal case with RGB colormap }
      if (map_entry_size = 4) then
        for i := 0 to pred(num_colors) do
        with output_ext_color_map[i] do
        begin
          b := GETJSAMPLE(cinfo^.colormap^[2]^[i]);
          g := GETJSAMPLE(cinfo^.colormap^[1]^[i]);
          r := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
          a := 0;
        end
      else
        for i := 0 to pred(num_colors) do
        with output_color_map[i] do
        begin
          b := GETJSAMPLE(cinfo^.colormap^[2]^[i]);
          g := GETJSAMPLE(cinfo^.colormap^[1]^[i]);
          r := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
        end;
    end
    else
    begin
      { Grayscale colormap (only happens with grayscale quantization) }
      if (map_entry_size = 4) then
        for i := 0 to pred(num_colors) do
        with output_ext_color_map[i] do
        begin
          b := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
          g := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
          r := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
          a := 0;
        end
      else
        for i := 0 to pred(num_colors) do
        with output_color_map[i] do
        begin
          b := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
          g := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
          r := GETJSAMPLE(cinfo^.colormap^[0]^[i]);
        end;
    end;
    i := num_colors;
  end
  else
  begin
    { If no colormap, must be grayscale data.  Generate a linear "map". }
    { Nomssi: do not use "num_colors" here, it should be 0 }
    if (map_entry_size = 4) then
      for i := 0 to pred(256) do
      with output_ext_color_map[i] do
      begin
        b := i;
        g := i;
        r := i;
        a := 0;
      end
    else
      for i := 0 to pred(256) do
      with output_color_map[i] do
      begin
        b := i;
        g := i;
        r := i;
      end;
    i := 256;
  end;
  { Pad colormap with zeros to ensure specified number of colormap entries }

  if (i > map_colors) then
    ERREXIT1(j_common_ptr(cinfo), JERR_TOO_MANY_COLORS, i);
  while (i < map_colors) do
  begin
    if (map_entry_size = 4) then
    with output_ext_color_map[i] do
    begin
      b := 0;
      g := 0;
      r := 0;
      a := 0;
    end
    else
    with output_color_map[i] do
    begin
      b := 0;
      g := 0;
      r := 0;
    end;
    Inc(i);
  end;
  if (map_entry_size = 4) then
    JFWRITE(outfile^, @output_ext_color_map, map_colors*4)
  else
    JFWRITE(outfile^, @output_color_map, map_colors*3);
end;


{METHODDEF}
procedure finish_output_bmp (cinfo : j_decompress_ptr;
                             dinfo : djpeg_dest_ptr); far;
var
  dest : bmp_dest_ptr;
  {register} outfile : FILEptr;
  image_ptr : JSAMPARRAY;
  {register} data_ptr : JSAMPLE_PTR;
  row : JDIMENSION;
  {register} col : JDIMENSION;
  progress : cd_progress_ptr;
begin
  dest := bmp_dest_ptr (dinfo);
  outfile := dest^.pub.output_file;
  progress := cd_progress_ptr (cinfo^.progress);

  { Write the header and colormap }
  if (dest^.is_os2) then
    write_os2_header(cinfo, dest)
  else
    write_bmp_header(cinfo, dest);

  { Write the file body from our virtual array }
  for row := cinfo^.output_height downto 1 do
  begin
    if (progress <> NIL) then
    begin
      progress^.pub.pass_counter := long (cinfo^.output_height - row);
      progress^.pub.pass_limit := long (cinfo^.output_height);
      progress^.pub.progress_monitor (j_common_ptr(cinfo));
    end;
    image_ptr := cinfo^.mem^.access_virt_sarray
      (j_common_ptr(cinfo), dest^.whole_image, row-1, JDIMENSION(1), FALSE);
    data_ptr := JSAMPLE_PTR(image_ptr^[0]);
    { Nomssi - This won't work for 12bit samples }
    JFWRITE(outfile^, data_ptr, dest^.row_width);
    {
    for col := pred(dest^.row_width) downto 0 do
    begin
      putc(GETJSAMPLE(data_ptr^), outfile);
      Inc(data_ptr);
    end;
    }
  end;
  if (progress <> NIL) then
    Inc(progress^.completed_extra_passes);

  { Make sure we wrote the output file OK }
  {fflush(outfile);
  if (ferror(outfile)) then
    ERREXIT(cinfo, JERR_FILE_WRITE);}
end;


{ The module selection routine for BMP format output. }

{GLOBAL}
function jinit_write_bmp (cinfo : j_decompress_ptr;
                          is_os2 : boolean) : djpeg_dest_ptr;
var
  dest : bmp_dest_ptr;
  row_width : JDIMENSION;
var
  progress : cd_progress_ptr;
begin
  { Create module interface object, fill in method pointers }
  dest := bmp_dest_ptr (
      cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
				  SIZEOF(bmp_dest_struct)) );
  dest^.pub.start_output := start_output_bmp;
  dest^.pub.finish_output := finish_output_bmp;
  dest^.is_os2 := is_os2;

  if (cinfo^.out_color_space = JCS_GRAYSCALE) then
  begin
    dest^.pub.put_pixel_rows := put_gray_rows;
  end
  else
    if (cinfo^.out_color_space = JCS_RGB) then
    begin
      if (cinfo^.quantize_colors) then
        dest^.pub.put_pixel_rows := put_gray_rows
      else
        dest^.pub.put_pixel_rows := put_pixel_rows;
  end
  else
    ERREXIT(j_common_ptr(cinfo), JERR_BMP_COLORSPACE);

  { Calculate output image dimensions so we can allocate space }
  jpeg_calc_output_dimensions(cinfo);

  { Determine width of rows in the BMP file (padded to 4-byte boundary). }
  row_width := cinfo^.output_width * cinfo^.output_components;
  dest^.data_width := row_width;
  while ((row_width and 3) <> 0) do
    Inc(row_width);
  dest^.row_width := row_width;
  dest^.pad_bytes := int (row_width - dest^.data_width);

  { Allocate space for inversion array, prepare for write pass }
  dest^.whole_image := cinfo^.mem^.request_virt_sarray
    (j_common_ptr(cinfo), JPOOL_IMAGE, FALSE,
     row_width, cinfo^.output_height, JDIMENSION (1));
  dest^.cur_output_row := 0;
  if (cinfo^.progress <> NIL) then
  begin
    progress := cd_progress_ptr (cinfo^.progress);
    Inc(progress^.total_extra_passes); { count file input as separate pass }
  end;

  { Create decompressor output buffer. }
  dest^.pub.buffer := cinfo^.mem^.alloc_sarray
    (j_common_ptr(cinfo), JPOOL_IMAGE, row_width, JDIMENSION (1));
  dest^.pub.buffer_height := 1;

  jinit_write_bmp := djpeg_dest_ptr(dest);
end;

end. { BMP_SUPPORTED }

⌨️ 快捷键说明

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