📄 jctrans.pas
字号:
Unit JcTrans;
{ This file contains library routines for transcoding compression,
that is, writing raw DCT coefficient arrays to an output JPEG file.
The routines in jcapimin.c will also be needed by a transcoder. }
{ Original : jctrans.c ; Copyright (C) 1995-1996, Thomas G. Lane. }
interface
{$I jconfig.inc}
uses
jmorecfg,
jinclude,
jdeferr,
jerror,
jutils,
jpeglib,
jcapimin, jcparam, jcomapi, jcmaster, jchuff, jcmarker;
{ Compression initialization for writing raw-coefficient data.
Before calling this, all parameters and a data destination must be set up.
Call jpeg_finish_compress() to actually write the data.
The number of passed virtual arrays must match cinfo^.num_components.
Note that the virtual arrays need not be filled or even realized at
the time write_coefficients is called; indeed, if the virtual arrays
were requested from this compression object's memory manager, they
typically will be realized during this routine and filled afterwards. }
{GLOBAL}
procedure jpeg_write_coefficients (cinfo : j_compress_ptr;
coef_arrays : jvirt_barray_tbl_ptr);
{ Initialize the compression object with default parameters,
then copy from the source object all parameters needed for lossless
transcoding. Parameters that can be varied without loss (such as
scan script and Huffman optimization) are left in their default states. }
{GLOBAL}
procedure jpeg_copy_critical_parameters (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr);
implementation
{ Forward declarations }
{LOCAL}
procedure transencode_master_selection(cinfo : j_compress_ptr;
coef_arrays : jvirt_barray_tbl_ptr);
forward;
{LOCAL}
procedure transencode_coef_controller(cinfo : j_compress_ptr;
coef_arrays : jvirt_barray_tbl_ptr);
forward;
{ Compression initialization for writing raw-coefficient data.
Before calling this, all parameters and a data destination must be set up.
Call jpeg_finish_compress() to actually write the data.
The number of passed virtual arrays must match cinfo^.num_components.
Note that the virtual arrays need not be filled or even realized at
the time write_coefficients is called; indeed, if the virtual arrays
were requested from this compression object's memory manager, they
typically will be realized during this routine and filled afterwards. }
{GLOBAL}
procedure jpeg_write_coefficients (cinfo : j_compress_ptr;
coef_arrays : jvirt_barray_tbl_ptr);
begin
if (cinfo^.global_state <> CSTATE_START) then
ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
{ Mark all tables to be written }
jpeg_suppress_tables(cinfo, FALSE);
{ (Re)initialize error mgr and destination modules }
cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo));
cinfo^.dest^.init_destination (cinfo);
{ Perform master selection of active modules }
transencode_master_selection(cinfo, coef_arrays);
{ Wait for jpeg_finish_compress() call }
cinfo^.next_scanline := 0; { so jpeg_write_marker works }
cinfo^.global_state := CSTATE_WRCOEFS;
end;
{ Initialize the compression object with default parameters,
then copy from the source object all parameters needed for lossless
transcoding. Parameters that can be varied without loss (such as
scan script and Huffman optimization) are left in their default states. }
{GLOBAL}
procedure jpeg_copy_critical_parameters (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr);
var
qtblptr : ^JQUANT_TBL_PTR;
incomp, outcomp : jpeg_component_info_ptr;
c_quant, slot_quant : JQUANT_TBL_PTR;
tblno, ci, coefi : int;
begin
{ Safety check to ensure start_compress not called yet. }
if (dstinfo^.global_state <> CSTATE_START) then
ERREXIT1(j_common_ptr(dstinfo), JERR_BAD_STATE, dstinfo^.global_state);
{ Copy fundamental image dimensions }
dstinfo^.image_width := srcinfo^.image_width;
dstinfo^.image_height := srcinfo^.image_height;
dstinfo^.input_components := srcinfo^.num_components;
dstinfo^.in_color_space := srcinfo^.jpeg_color_space;
{ Initialize all parameters to default values }
jpeg_set_defaults(dstinfo);
{ jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
Fix it to get the right header markers for the image colorspace. }
jpeg_set_colorspace(dstinfo, srcinfo^.jpeg_color_space);
dstinfo^.data_precision := srcinfo^.data_precision;
dstinfo^.CCIR601_sampling := srcinfo^.CCIR601_sampling;
{ Copy the source's quantization tables. }
for tblno := 0 to pred(NUM_QUANT_TBLS) do
begin
if (srcinfo^.quant_tbl_ptrs[tblno] <> NIL) then
begin
qtblptr := @dstinfo^.quant_tbl_ptrs[tblno];
if (qtblptr^ = NIL) then
qtblptr^ := jpeg_alloc_quant_table(j_common_ptr(dstinfo));
MEMCOPY(@(qtblptr^)^.quantval,
@srcinfo^.quant_tbl_ptrs[tblno]^.quantval,
SIZEOF((qtblptr^)^.quantval));
(qtblptr^)^.sent_table := FALSE;
end;
end;
{ Copy the source's per-component info.
Note we assume jpeg_set_defaults has allocated the dest comp_info array. }
dstinfo^.num_components := srcinfo^.num_components;
if (dstinfo^.num_components < 1) or
(dstinfo^.num_components > MAX_COMPONENTS) then
ERREXIT2(j_common_ptr(dstinfo), JERR_COMPONENT_COUNT,
dstinfo^.num_components, MAX_COMPONENTS);
incomp := srcinfo^.comp_info;
outcomp := dstinfo^.comp_info;
for ci := 0 to pred(dstinfo^.num_components) do
begin
outcomp^.component_id := incomp^.component_id;
outcomp^.h_samp_factor := incomp^.h_samp_factor;
outcomp^.v_samp_factor := incomp^.v_samp_factor;
outcomp^.quant_tbl_no := incomp^.quant_tbl_no;
{ Make sure saved quantization table for component matches the qtable
slot. If not, the input file re-used this qtable slot.
IJG encoder currently cannot duplicate this. }
tblno := outcomp^.quant_tbl_no;
if (tblno < 0) or (tblno >= NUM_QUANT_TBLS) or
(srcinfo^.quant_tbl_ptrs[tblno] = NIL) then
ERREXIT1(j_common_ptr(dstinfo), JERR_NO_QUANT_TABLE, tblno);
slot_quant := srcinfo^.quant_tbl_ptrs[tblno];
c_quant := incomp^.quant_table;
if (c_quant <> NIL) then
begin
for coefi := 0 to pred(DCTSIZE2) do
begin
if (c_quant^.quantval[coefi] <> slot_quant^.quantval[coefi]) then
ERREXIT1(j_common_ptr(dstinfo), JERR_MISMATCHED_QUANT_TABLE, tblno);
end;
end;
{ Note: we do not copy the source's Huffman table assignments;
instead we rely on jpeg_set_colorspace to have made a suitable choice. }
Inc(incomp);
Inc(outcomp);
end;
end;
{ Master selection of compression modules for transcoding.
This substitutes for jcinit.c's initialization of the full compressor. }
{LOCAL}
procedure transencode_master_selection (cinfo : j_compress_ptr;
coef_arrays : jvirt_barray_tbl_ptr);
begin
{ Although we don't actually use input_components for transcoding,
jcmaster.c's initial_setup will complain if input_components is 0. }
cinfo^.input_components := 1;
{ Initialize master control (includes parameter checking/processing) }
jinit_c_master_control(cinfo, TRUE { transcode only });
{ Entropy encoding: either Huffman or arithmetic coding. }
if (cinfo^.arith_code) then
begin
ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL);
end
else
begin
if (cinfo^.progressive_mode) then
begin
{$ifdef C_PROGRESSIVE_SUPPORTED}
jinit_phuff_encoder(cinfo);
{$else}
ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
{$endif}
end
else
jinit_huff_encoder(cinfo);
end;
{ We need a special coefficient buffer controller. }
transencode_coef_controller(cinfo, coef_arrays);
jinit_marker_writer(cinfo);
{ We can now tell the memory manager to allocate virtual arrays. }
cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo));
{ Write the datastream header (SOI) immediately.
Frame and scan headers are postponed till later.
This lets application insert special markers after the SOI. }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -