📄 tif_ojpeg.c
字号:
encapsulations in "new format" files, try to synthesize the value of a
modern "JPEGTables" TIFF record by scanning the JPEG data from just past
the "Start of Information" (SOI) marker until something other than a
legitimate "table" marker is found, as defined in ISO DIS 10918-1
Appending B.2.4; namely:
-- Define Quantization Table (DQT)
-- Define Huffman Table (DHT)
-- Define Arithmetic Coding table (DAC)
-- Define Restart Interval (DRI)
-- Comment (COM)
-- Application data (APPn)
For convenience, we also accept "Expansion" (EXP) markers, although they
are apparently not a part of normal "table" data.
*/
sp->jpegtables = p = (unsigned char *)sp->src.next_input_byte;
end_of_data = p + sp->src.bytes_in_buffer;
p += 2;
while (p < end_of_data && p[0] == 0xFF)
switch (p[1])
{
default : goto L;
case 0xC0: /* SOF0 */
case 0xC1: /* SOF1 */
case 0xC2: /* SOF2 */
case 0xC3: /* SOF3 */
case 0xC4: /* DHT */
case 0xC5: /* SOF5 */
case 0xC6: /* SOF6 */
case 0xC7: /* SOF7 */
case 0xC9: /* SOF9 */
case 0xCA: /* SOF10 */
case 0xCB: /* SOF11 */
case 0xCC: /* DAC */
case 0xCD: /* SOF13 */
case 0xCE: /* SOF14 */
case 0xCF: /* SOF15 */
case 0xDB: /* DQT */
case 0xDD: /* DRI */
case 0xDF: /* EXP */
case 0xE0: /* APP0 */
case 0xE1: /* APP1 */
case 0xE2: /* APP2 */
case 0xE3: /* APP3 */
case 0xE4: /* APP4 */
case 0xE5: /* APP5 */
case 0xE6: /* APP6 */
case 0xE7: /* APP7 */
case 0xE8: /* APP8 */
case 0xE9: /* APP9 */
case 0xEA: /* APP10 */
case 0xEB: /* APP11 */
case 0xEC: /* APP12 */
case 0xED: /* APP13 */
case 0xEE: /* APP14 */
case 0xEF: /* APP15 */
case 0xFE: /* COM */
p += (p[2] << 8 | p[3]) + 2;
};
L: if (p - (unsigned char *)sp->jpegtables > 2) /* fake "JPEGTables" */
{
/* In case our client application asks, pretend that this image file
contains a modern "JPEGTables" TIFF record by copying to a buffer
the initial part of the JFIF bit-stream that we just scanned, from
the SOI marker through the "metadata" tables, then append an EOI
marker and flag the "JPEGTables" TIFF record as "present".
*/
sp->jpegtables_length = p - (unsigned char*)sp->jpegtables + 2;
p = sp->jpegtables;
if (!(sp->jpegtables = _TIFFmalloc(sp->jpegtables_length)))
{
TIFFError(module,no_jtable_space);
return 0;
};
_TIFFmemcpy(sp->jpegtables,p,sp->jpegtables_length-2);
p = (unsigned char *)sp->jpegtables + sp->jpegtables_length;
p[-2] = 0xFF; p[-1] = JPEG_EOI; /* Append EOI marker */
TIFFSetFieldBit(tif,FIELD_JPEGTABLES);
tif->tif_flags |= TIFF_DIRTYDIRECT;
}
else sp->jpegtables = 0; /* Don't simulate "JPEGTables" */
if (TIFFojpeg_read_header(sp,TRUE) != JPEG_HEADER_OK) return 0;
if ( sp->cinfo.d.image_width != segment_width
|| sp->cinfo.d.image_height != segment_height
)
{
TIFFError(module,"Improper JPEG strip/tile size");
return 0;
};
if ( ( td->td_planarconfig == PLANARCONFIG_CONTIG
? td->td_samplesperpixel
: 1
) != sp->cinfo.d.num_components
)
{
TIFFError(module,"Improper JPEG component count");
return 0;
};
if (sp->cinfo.d.data_precision != td->td_bitspersample)
{
TIFFError(module,"Improper JPEG data precision");
return 0;
};
/*if (td->td_planarconfig == PLANARCONFIG_CONTIG)
{ int ci;
// Component 0 should have expected sampling factors.
if ( sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling
|| sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling
)
{
TIFFError(module,bad_factors);
return 0;
};
ci = 1; // The rest should have sampling factors 1,1
do if ( sp->cinfo.d.comp_info[ci].h_samp_factor != 1
|| sp->cinfo.d.comp_info[ci].v_samp_factor != 1
)
{
TIFFError(module,bad_factors);
return 0;
}
while (++ci < sp->cinfo.d.num_components);
}
else
// PLANARCONFIG_SEPARATE's single component should have sampling factors
if ( sp->cinfo.d.comp_info[0].h_samp_factor != 1
|| sp->cinfo.d.comp_info[0].v_samp_factor != 1
)
{
TIFFError(module,bad_factors);
return 0;
}
*/
}
else /* not JFIF image */
{ int (*save)(j_decompress_ptr cinfo) = sp->cinfo.d.marker->read_markers;
register int i;
/* We're not assuming that this file's JPEG bit stream has any header
"metadata", so fool the JPEG Library into thinking that we read a
"Start of Input" (SOI) marker and a "Start of Frame" (SOFx) marker, then
force it to read a simulated "Start of Scan" (SOS) marker when we call
"TIFFojpeg_read_header()" below. This should cause the JPEG Library to
establish reasonable defaults.
*/
sp->cinfo.d.marker->saw_SOI = /* Pretend we saw SOI marker */
sp->cinfo.d.marker->saw_SOF = TRUE; /* Pretend we saw SOF marker */
sp->cinfo.d.marker->read_markers =
sp->is_WANG ? suspend : fake_SOS_marker;
sp->cinfo.d.global_state = DSTATE_INHEADER;
sp->cinfo.d.Se = DCTSIZE2-1; /* Suppress JPEG Library warning */
sp->cinfo.d.image_width = segment_width;
sp->cinfo.d.image_height = segment_height;
sp->cinfo.d.data_precision = td->td_bitspersample;
/* The following color-space initialization, including the complicated
"switch"-statement below, essentially duplicates the logic used by the
JPEG Library's "jpeg_init_colorspace()" subroutine during compression.
*/
sp->cinfo.d.num_components = td->td_planarconfig == PLANARCONFIG_CONTIG
? td->td_samplesperpixel
: 1;
sp->cinfo.d.comp_info = (jpeg_component_info *)
(*sp->cinfo.d.mem->alloc_small)
( &sp->cinfo.comm
, JPOOL_IMAGE
, sp->cinfo.d.num_components * sizeof *sp->cinfo.d.comp_info
);
i = 0;
do
{
sp->cinfo.d.comp_info[i].component_index = i;
sp->cinfo.d.comp_info[i].component_needed = TRUE;
sp->cinfo.d.cur_comp_info[i] = &sp->cinfo.d.comp_info[i];
}
while (++i < sp->cinfo.d.num_components);
switch (in_color_space)
{
case JCS_UNKNOWN :
i = 0;
do
{
sp->cinfo.d.comp_info[i].component_id = i;
sp->cinfo.d.comp_info[i].h_samp_factor =
sp->cinfo.d.comp_info[i].v_samp_factor = 1;
}
while (++i < sp->cinfo.d.num_components);
break;
case JCS_GRAYSCALE:
sp->cinfo.d.comp_info[0].component_id =
sp->cinfo.d.comp_info[0].h_samp_factor =
sp->cinfo.d.comp_info[0].v_samp_factor = 1;
break;
case JCS_RGB :
sp->cinfo.d.comp_info[0].component_id = 'R';
sp->cinfo.d.comp_info[1].component_id = 'G';
sp->cinfo.d.comp_info[2].component_id = 'B';
i = 0;
do sp->cinfo.d.comp_info[i].h_samp_factor =
sp->cinfo.d.comp_info[i].v_samp_factor = 1;
while (++i < sp->cinfo.d.num_components);
break;
case JCS_CMYK :
sp->cinfo.d.comp_info[0].component_id = 'C';
sp->cinfo.d.comp_info[1].component_id = 'Y';
sp->cinfo.d.comp_info[2].component_id = 'M';
sp->cinfo.d.comp_info[3].component_id = 'K';
i = 0;
do sp->cinfo.d.comp_info[i].h_samp_factor =
sp->cinfo.d.comp_info[i].v_samp_factor = 1;
while (++i < sp->cinfo.d.num_components);
break;
case JCS_YCbCr :
i = 0;
do
{
sp->cinfo.d.comp_info[i].component_id = i+1;
sp->cinfo.d.comp_info[i].h_samp_factor =
sp->cinfo.d.comp_info[i].v_samp_factor = 1;
sp->cinfo.d.comp_info[i].quant_tbl_no =
sp->cinfo.d.comp_info[i].dc_tbl_no =
sp->cinfo.d.comp_info[i].ac_tbl_no = i > 0;
}
while (++i < sp->cinfo.d.num_components);
sp->cinfo.d.comp_info[0].h_samp_factor = sp->h_sampling;
sp->cinfo.d.comp_info[0].v_samp_factor = sp->v_sampling;
};
sp->cinfo.d.comps_in_scan = sp->cinfo.d.num_components;
i = TIFFojpeg_read_header(sp,(unsigned char)(!sp->is_WANG));
sp->cinfo.d.marker->read_markers = save; /* Restore input method */
if (sp->is_WANG) /* Microsoft Wang Imaging for Windows file */
{
if (i != JPEG_SUSPENDED) return 0;
/* BOGOSITY ALERT! Files generated by Microsoft's Wang Imaging
application are a special--and, technically
illegal--case. A JPEG SOS marker and rest of the data stream should
be located at the end of the file, in a position identified by the
0th Strip offset.
*/
i = td->td_nstrips - 1;
sp->src.next_input_byte = tif->tif_base + td->td_stripoffset[0];
sp->src.bytes_in_buffer = td->td_stripoffset[i] -
td->td_stripoffset[0] + td->td_stripbytecount[i];
i = TIFFojpeg_read_header(sp,TRUE);
};
if (i != JPEG_HEADER_OK) return 0;
};
/* The JPEG Library doesn't seem to be as smart as we are about choosing
suitable default input- and output color spaces for decompression, so fix
things up here.
*/
sp->cinfo.d.out_color_space =
((sp->cinfo.d.jpeg_color_space = in_color_space) == JCS_YCbCr)
? (sp->jpegcolormode == JPEGCOLORMODE_RGB ? JCS_RGB : JCS_YCbCr)
: JCS_UNKNOWN; /* Suppress color-space handling */
tif->tif_decoderow = tif->tif_decodestrip = tif->tif_decodetile =
(sp->cinfo.d.raw_data_out = downsampled_output)
? OJPEGDecodeRaw : OJPEGDecode;
if (!TIFFojpeg_start_decompress(sp)) return 0; /* Start JPEG decompressor */
if (downsampled_output) /* allocate downsampled-data buffers */
{
if (!alloc_downsampled_buffers(tif,sp->cinfo.d.comp_info,
sp->cinfo.d.num_components)
) return 0;
sp->scancount = DCTSIZE; /* mark buffer empty */
};
return 1;
# undef td
}
static int
OJPEGVSetField(register TIFF *tif,ttag_t tag,va_list ap)
{ uint32 v32;
register OJPEGState *sp = OJState(tif);
# define td (&tif->tif_dir)
switch (tag)
{
# ifdef COLORIMETRY_SUPPORT
/* If a "ReferenceBlackWhite" TIFF tag appears in the file explicitly, undo
any modified default definition that we might have installed below, then
install the real one.
*/
case TIFFTAG_REFERENCEBLACKWHITE : if (td->td_refblackwhite)
{
_TIFFfree(td->td_refblackwhite);
td->td_refblackwhite = 0;
};
# endif /* COLORIMETRY_SUPPORT */
default : return
(*sp->vsetparent)(tif,tag,ap);
# ifdef COLORIMETRY_SUPPORT
/* BEWARE OF KLUDGE: Some old-format JPEG-in-TIFF files, including those
created by Microsoft's Wang Imaging application,
illegally omit a "ReferenceBlackWhite" TIFF tag, even though the TIFF
specification's default is intended for the RGB color space and is in-
appropriate for the YCbCr color space ordinarily used for JPEG images.
Since many TIFF client applications request the value of this tag
immediately after a TIFF image directory is parsed, and before any other
code in this module receives control, we are forced to fix this problem
very early in image-file processing. Fortunately, legal TIFF files are
supposed to store their tags in numeric order, so a mandatory
"PhotometricInterpretation" tag should always appear before an optional
"ReferenceBlackWhite" tag. So, we slyly
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -