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

📄 jquant1.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 3 页
字号:
                                input_buf : JSAMPARRAY;
		                output_buf : JSAMPARRAY;
                                num_rows : int); far;
{ Fast path for out_color_components=3, with ordered dithering }
var
  cquantize : my_cquantize_ptr;
  pixcode : int; {register}
  input_ptr : JSAMPLE_PTR; {register}
  output_ptr : JSAMPLE_PTR; {register}
  colorindex0 : JSAMPROW;
  colorindex1 : JSAMPROW;
  colorindex2 : JSAMPROW;
  dither0 : ^ODITHER_vector;    { points to active row of dither matrix }
  dither1 : ^ODITHER_vector;
  dither2 : ^ODITHER_vector;
  row_index, col_index : int;   { current indexes into dither matrix }
  row : int;
  col : JDIMENSION;
  width : JDIMENSION;
var
  pad_offset : int;
begin
  cquantize := my_cquantize_ptr (cinfo^.cquantize);
  colorindex0 := (cquantize^.colorindex)^[0];
  colorindex1 := (cquantize^.colorindex)^[1];
  colorindex2 := (cquantize^.colorindex)^[2];
  width := cinfo^.output_width;

  { Nomssi: work around negative offset }
  if my_cquantize_ptr (cinfo^.cquantize)^.is_padded then
    pad_offset := MAXJSAMPLE
  else
    pad_offset := 0;

  Dec(JSAMPLE_PTR(colorindex0), pad_offset);
  Dec(JSAMPLE_PTR(colorindex1), pad_offset);
  Dec(JSAMPLE_PTR(colorindex2), pad_offset);

  for row := 0 to pred(num_rows) do
  begin
    row_index := cquantize^.row_index;
    input_ptr := JSAMPLE_PTR(input_buf^[row]);
    output_ptr := JSAMPLE_PTR(output_buf^[row]);
    dither0 := @(cquantize^.odither[0]^[row_index]);
    dither1 := @(cquantize^.odither[1]^[row_index]);
    dither2 := @(cquantize^.odither[2]^[row_index]);
    col_index := 0;


    for col := pred(width) downto 0 do
    begin
      pixcode := GETJSAMPLE(colorindex0^[GETJSAMPLE(input_ptr^) + pad_offset
                                         + dither0^[col_index]]);
      Inc(input_ptr);
      Inc(pixcode, GETJSAMPLE(colorindex1^[GETJSAMPLE(input_ptr^) + pad_offset
                                           + dither1^[col_index]]));
      Inc(input_ptr);
      Inc(pixcode, GETJSAMPLE(colorindex2^[GETJSAMPLE(input_ptr^) + pad_offset
                                           + dither2^[col_index]]));
      Inc(input_ptr);
      output_ptr^ := JSAMPLE (pixcode);
      Inc(output_ptr);
      col_index := (col_index + 1) and ODITHER_MASK;
    end;
    row_index := (row_index + 1) and ODITHER_MASK;
    cquantize^.row_index := row_index;
  end;
end;


{METHODDEF}
procedure quantize_fs_dither (cinfo : j_decompress_ptr;
                              input_buf : JSAMPARRAY;
		              output_buf : JSAMPARRAY;
                              num_rows : int); far;
{ General case, with Floyd-Steinberg dithering }
var
  cquantize : my_cquantize_ptr;
  cur : LOCFSERROR; {register}  { current error or pixel value }
  belowerr : LOCFSERROR;        { error for pixel below cur }
  bpreverr : LOCFSERROR;        { error for below/prev col }
  bnexterr : LOCFSERROR;        { error for below/next col }
  delta : LOCFSERROR;
  prev_errorptr,
  errorptr : FSERRORPTR; {register} { => fserrors[] at column before current }
  input_ptr,                {register}
  output_ptr : JSAMPLE_PTR; {register}
  colorindex_ci : JSAMPROW;
  colormap_ci : JSAMPROW;
  pixcode : int;
  nc : int;
  dir : int;			{ 1 for left-to-right, -1 for right-to-left }
  dirnc : int;			{ dir * nc }
  ci : int;
  row : int;
  col : JDIMENSION;
  width : JDIMENSION;
  range_limit : range_limit_table_ptr;
begin
  cquantize := my_cquantize_ptr (cinfo^.cquantize);
  nc := cinfo^.out_color_components;
  width := cinfo^.output_width;
  range_limit := cinfo^.sample_range_limit;

  for row := 0 to pred(num_rows) do
  begin
    { Initialize output values to 0 so can process components separately }
    jzero_far( (output_buf)^[row],
               size_t(width * SIZEOF(JSAMPLE)));
    for ci := 0 to pred(nc) do
    begin
      input_ptr := JSAMPLE_PTR(@ input_buf^[row]^[ci]);
      output_ptr := JSAMPLE_PTR(output_buf^[row]);
      errorptr := FSERRORPTR(cquantize^.fserrors[ci]); { => entry before first column }
      if (cquantize^.on_odd_row) then
      begin
	{ work right to left in this row }
	Inc(input_ptr, (width-1) * nc); { so point to rightmost pixel }
	Inc(output_ptr, width-1);
	dir := -1;
	dirnc := -nc;
	Inc(errorptr, (width+1)); { => entry after last column }
      end
      else
      begin
	{ work left to right in this row }
	dir := 1;
	dirnc := nc;
        {errorptr := cquantize^.fserrors[ci];}
      end;

      colorindex_ci := cquantize^.colorindex^[ci];

      colormap_ci := (cquantize^.sv_colormap)^[ci];
      { Preset error values: no error propagated to first pixel from left }
      cur := 0;
      { and no error propagated to row below yet }
      belowerr := 0;
      bpreverr := 0;

      for col := pred(width) downto 0 do
      begin
        prev_errorptr := errorptr;
	Inc(errorptr, dir);  { advance errorptr to current column }

	{ cur holds the error propagated from the previous pixel on the
	  current line.  Add the error propagated from the previous line
	  to form the complete error correction term for this pixel, and
	  round the error term (which is expressed * 16) to an integer.
	  RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
	  for either sign of the error value.
	  Note: errorptr points to *previous* column's array entry. }

        cur := (cur + errorptr^ + 8) div 16;

	{ Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
	  The maximum error is +- MAXJSAMPLE; this sets the required size
	  of the range_limit array. }

	Inc( cur, GETJSAMPLE(input_ptr^));
	cur := GETJSAMPLE(range_limit^[cur]);
	{ Select output value, accumulate into output code for this pixel }
	pixcode := GETJSAMPLE(colorindex_ci^[cur]);
	Inc(output_ptr^, JSAMPLE (pixcode));
	{ Compute actual representation error at this pixel }
	{ Note: we can do this even though we don't have the final }
	{ pixel code, because the colormap is orthogonal. }
	Dec(cur, GETJSAMPLE(colormap_ci^[pixcode]));
	{ Compute error fractions to be propagated to adjacent pixels.
	  Add these into the running sums, and simultaneously shift the
	  next-line error sums left by 1 column. }

	bnexterr := cur;
	delta := cur * 2;
	Inc(cur, delta);        { form error * 3 }
	prev_errorptr^ := FSERROR (bpreverr + cur);
	Inc(cur, delta);        { form error * 5 }
	bpreverr := belowerr + cur;
	belowerr := bnexterr;
	Inc(cur, delta);        { form error * 7 }
	{ At this point cur contains the 7/16 error value to be propagated
	  to the next pixel on the current line, and all the errors for the
	  next line have been shifted over. We are therefore ready to move on. }

	Inc(input_ptr, dirnc);  { advance input ptr to next column }
	Inc(output_ptr, dir);   { advance output ptr to next column }

      end;
      { Post-loop cleanup: we must unload the final error value into the
        final fserrors[] entry.  Note we need not unload belowerr because
        it is for the dummy column before or after the actual array. }

      errorptr^ := FSERROR (bpreverr); { unload prev err into array }
      { Nomssi : ?? }
    end;
    cquantize^.on_odd_row := not cquantize^.on_odd_row;
  end;
end;


{ Allocate workspace for Floyd-Steinberg errors. }

{LOCAL}
procedure alloc_fs_workspace (cinfo : j_decompress_ptr);
var
  cquantize : my_cquantize_ptr;
  arraysize : size_t;
  i : int;
begin
  cquantize := my_cquantize_ptr (cinfo^.cquantize);
  arraysize := size_t ((cinfo^.output_width + 2) * SIZEOF(FSERROR));
  for i := 0 to pred(cinfo^.out_color_components) do
  begin
    cquantize^.fserrors[i] := FS_ERROR_FIELD_PTR(
      cinfo^.mem^.alloc_large(j_common_ptr(cinfo), JPOOL_IMAGE, arraysize));
  end;
end;


{ Initialize for one-pass color quantization. }

{METHODDEF}
procedure start_pass_1_quant (cinfo : j_decompress_ptr;
                              is_pre_scan : boolean); far;
var
  cquantize : my_cquantize_ptr;
  arraysize : size_t;
  i : int;
begin
  cquantize := my_cquantize_ptr (cinfo^.cquantize);
  { Install my colormap. }
  cinfo^.colormap := cquantize^.sv_colormap;
  cinfo^.actual_number_of_colors := cquantize^.sv_actual;

  { Initialize for desired dithering mode. }
  case (cinfo^.dither_mode) of
  JDITHER_NONE:
    if (cinfo^.out_color_components = 3) then
      cquantize^.pub.color_quantize := color_quantize3
    else
      cquantize^.pub.color_quantize := color_quantize;
  JDITHER_ORDERED:
    begin
      if (cinfo^.out_color_components = 3) then
        cquantize^.pub.color_quantize := quantize3_ord_dither
      else
        cquantize^.pub.color_quantize := quantize_ord_dither;
      cquantize^.row_index := 0;    { initialize state for ordered dither }
      { If user changed to ordered dither from another mode,
        we must recreate the color index table with padding.
        This will cost extra space, but probably isn't very likely. }

      if (not cquantize^.is_padded) then
        create_colorindex(cinfo);
      { Create ordered-dither tables if we didn't already. }
      if (cquantize^.odither[0] = NIL) then
        create_odither_tables(cinfo);
    end;
  JDITHER_FS:
    begin
      cquantize^.pub.color_quantize := quantize_fs_dither;
      cquantize^.on_odd_row := FALSE; { initialize state for F-S dither }
      { Allocate Floyd-Steinberg workspace if didn't already. }
      if (cquantize^.fserrors[0] = NIL) then
        alloc_fs_workspace(cinfo);
      { Initialize the propagated errors to zero. }
      arraysize := size_t ((cinfo^.output_width + 2) * SIZEOF(FSERROR));
      for i := 0 to pred(cinfo^.out_color_components) do
        jzero_far({far} pointer( cquantize^.fserrors[i] ), arraysize);
    end;
  else
    ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
  end;
end;


{ Finish up at the end of the pass. }

{METHODDEF}
procedure finish_pass_1_quant (cinfo : j_decompress_ptr); far;
begin
  { no work in 1-pass case }
end;


{ Switch to a new external colormap between output passes.
  Shouldn't get to this module! }

{METHODDEF}
procedure new_color_map_1_quant (cinfo : j_decompress_ptr); far;
begin
  ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE);
end;


{ Module initialization routine for 1-pass color quantization. }

{GLOBAL}
procedure jinit_1pass_quantizer (cinfo : j_decompress_ptr);
var
  cquantize : my_cquantize_ptr;
begin
  cquantize := my_cquantize_ptr(
     cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
				SIZEOF(my_cquantizer)));
  cinfo^.cquantize := jpeg_color_quantizer_ptr(cquantize);
  cquantize^.pub.start_pass := start_pass_1_quant;
  cquantize^.pub.finish_pass := finish_pass_1_quant;
  cquantize^.pub.new_color_map := new_color_map_1_quant;
  cquantize^.fserrors[0] := NIL; { Flag FS workspace not allocated }
  cquantize^.odither[0] := NIL;	{ Also flag odither arrays not allocated }

  { Make sure my internal arrays won't overflow }
  if (cinfo^.out_color_components > MAX_Q_COMPS) then
    ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
  { Make sure colormap indexes can be represented by JSAMPLEs }
  if (cinfo^.desired_number_of_colors > (MAXJSAMPLE+1)) then
    ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);

  { Create the colormap and color index table. }
  create_colormap(cinfo);
  create_colorindex(cinfo);

  { Allocate Floyd-Steinberg workspace now if requested.
    We do this now since it is FAR storage and may affect the memory
    manager's space calculations.  If the user changes to FS dither
    mode in a later pass, we will allocate the space then, and will
    possibly overrun the max_memory_to_use setting. }

  if (cinfo^.dither_mode = JDITHER_FS) then
    alloc_fs_workspace(cinfo);
end;


end.

⌨️ 快捷键说明

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