📄 tif_ojpeg.c
字号:
static intOJPEGPostEncode(register TIFF *tif) { register OJPEGState *sp = OJState(tif); /* Finish up at the end of a strip or tile. */ if (sp->scancount > 0) /* emit partial buffer of down-sampled data */ { JDIMENSION n;# ifdef C_LOSSLESS_SUPPORTED if ( sp->scancount < sp->cinfo.c.data_unit && sp->cinfo.c.num_components > 0 )# else if (sp->scancount < DCTSIZE && sp->cinfo.c.num_components > 0)# endif { int ci = 0, /* Pad the data vertically */# ifdef C_LOSSLESS_SUPPORTED size = sp->cinfo.c.data_unit;# else size = DCTSIZE;# endif register jpeg_component_info *compptr = sp->cinfo.c.comp_info; do# ifdef C_LOSSLESS_SUPPORTED { tsize_t row_width = compptr->width_in_data_units# else tsize_t row_width = compptr->width_in_blocks# endif *size*sizeof(JSAMPLE); int ypos = sp->scancount*compptr->v_samp_factor; do _TIFFmemcpy( (tdata_t)sp->ds_buffer[ci][ypos] , (tdata_t)sp->ds_buffer[ci][ypos-1] , row_width ); while (++ypos < compptr->v_samp_factor*size); } while (++compptr,++ci < sp->cinfo.c.num_components); }; n = sp->cinfo.c.max_v_samp_factor*size; if (CALLJPEG(sp,-1,jpeg_write_raw_data(&sp->cinfo.c,sp->ds_buffer,n)) != n) return 0; }; return CALLVJPEG(sp,jpeg_finish_compress(&sp->cinfo.c)); }#endif /* never *//* JPEG Decoding begins here. *//*ARGSUSED*/ static intOJPEGDecode(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s) { tsize_t bytesperline = isTiled(tif) ? TIFFTileRowSize(tif) : tif->tif_scanlinesize, rows; /* No. of unprocessed rows in file */ register OJPEGState *sp = OJState(tif); /* Decode a chunk of pixels, where the input data has not NOT been down- sampled, or else the TIFF Library's client has used the "JPEGColorMode" TIFF pseudo-tag to request that the JPEG Library do color-space conversion; this is the normal case. The data is expected to be read in scan-line multiples, and this subroutine is called for both pixel-interleaved and separate color planes. WARNING: Unlike "OJPEGDecodeRawContig()", below, the no. of Bytes in each decoded row is calculated here as "bytesperline" instead of using "sp->bytesperline", which might be a little smaller. This can occur for an old tiled image whose width isn't a multiple of 8 pixels. That's illegal according to the TIFF Version 6 specification, but some test files, like "zackthecat.tif", were built that way. In those cases, we want to embed the image's true width in our caller's buffer (which is presumably allocated according to the expected tile width) by effectively "padding" it with unused Bytes at the end of each row. */ if ( (cc /= bytesperline) /* No. of complete rows in caller's buffer */ > (rows = sp->cinfo.d.output_height - sp->cinfo.d.output_scanline) ) cc = rows; while (--cc >= 0) { if ( CALLJPEG(sp,-1,jpeg_read_scanlines(&sp->cinfo.d,(JSAMPARRAY)&buf,1)) != 1 ) return 0; buf += bytesperline; ++tif->tif_row; }; /* BEWARE OF KLUDGE: If our input file was produced by Microsoft's Wang Imaging for Windows application, the DC coefficients of each JPEG image component (Y,Cb,Cr) must be reset at the end of each TIFF "strip", and any JPEG data bits remaining in the current Byte of the decoder's input buffer must be discarded. To do so, we create an "ad hoc" interface in the "jdhuff.c" module of IJG JPEG Library Version 6 (module "jdshuff.c", if Ken Murchison's lossless-Huffman patch is applied), and we invoke that interface here after decoding each "strip". */ if (sp->is_WANG) jpeg_reset_huff_decode(&sp->cinfo.d); return 1; }/*ARGSUSED*/ static intOJPEGDecodeRawContig(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s) { tsize_t rows; /* No. of unprocessed rows in file */ JDIMENSION lines_per_MCU, size; register OJPEGState *sp = OJState(tif); /* Decode a chunk of pixels, where the input data has pixel-interleaved color planes, some of which have been down-sampled, but the TIFF Library's client has NOT used the "JPEGColorMode" TIFF pseudo-tag to request that the JPEG Library do color-space conversion. In other words, we must up-sample/ expand/duplicate image components according to the image's sampling factors, without changing its color space. The data is expected to be read in scan- line multiples. */ if ( (cc /= sp->bytesperline) /* No. of complete rows in caller's buffer */ > (rows = sp->cinfo.d.output_height - sp->cinfo.d.output_scanline) ) cc = rows; lines_per_MCU = sp->cinfo.d.max_v_samp_factor# ifdef D_LOSSLESS_SUPPORTED * (size = sp->cinfo.d.min_codec_data_unit);# else * (size = DCTSIZE);# endif while (--cc >= 0) { int clumpoffset, ci; register jpeg_component_info *compptr; if (sp->scancount >= size) /* reload downsampled-data buffers */ { if ( CALLJPEG(sp,-1,jpeg_read_raw_data(&sp->cinfo.d,sp->ds_buffer,lines_per_MCU)) != lines_per_MCU ) return 0; sp->scancount = 0; }; /* The fastest way to separate the data is: make 1 pass over the scan line for each row of each component. */ clumpoffset = ci = 0; compptr = sp->cinfo.d.comp_info; do { int ypos = 0; if (compptr->h_samp_factor == 1) /* fast path */ do { register JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*compptr->v_samp_factor+ypos], *outptr = (JSAMPLE *)buf + clumpoffset; register int clumps_per_line = compptr->downsampled_width; do *outptr = *inptr++; while ((outptr += sp->samplesperclump),--clumps_per_line > 0); } while ( (clumpoffset += compptr->h_samp_factor) , ++ypos < compptr->v_samp_factor ); else /* general case */ do { register JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*compptr->v_samp_factor+ypos], *outptr = (JSAMPLE *)buf + clumpoffset; register int clumps_per_line = compptr->downsampled_width; do { register int xpos = 0; do outptr[xpos] = *inptr++; while (++xpos < compptr->h_samp_factor); } while ((outptr += sp->samplesperclump),--clumps_per_line > 0); } while ( (clumpoffset += compptr->h_samp_factor) , ++ypos < compptr->v_samp_factor ); } while (++compptr,++ci < sp->cinfo.d.num_components); ++sp->scancount; buf += sp->bytesperline; ++tif->tif_row; }; /* BEWARE OF KLUDGE: If our input file was produced by Microsoft's Wang Imaging for Windows application, the DC coefficients of each JPEG image component (Y,Cb,Cr) must be reset at the end of each TIFF "strip", and any JPEG data bits remaining in the current Byte of the decoder's input buffer must be discarded. To do so, we create an "ad hoc" interface in the "jdhuff.c" module of IJG JPEG Library Version 6 (module "jdshuff.c", if Ken Murchison's lossless-Huffman patch is applied), and we invoke that interface here after decoding each "strip". */ if (sp->is_WANG) jpeg_reset_huff_decode(&sp->cinfo.d); return 1; }/*ARGSUSED*/ static intOJPEGDecodeRawSeparate(TIFF *tif,register tidata_t buf,tsize_t cc,tsample_t s) { tsize_t rows; /* No. of unprocessed rows in file */ JDIMENSION lines_per_MCU, size, /* ...of MCU */ v; /* Component's vertical up-sampling ratio */ register OJPEGState *sp = OJState(tif); register jpeg_component_info *compptr = sp->cinfo.d.comp_info + s; /* Decode a chunk of pixels, where the input data has separate color planes, some of which have been down-sampled, but the TIFF Library's client has NOT used the "JPEGColorMode" TIFF pseudo-tag to request that the JPEG Library do color-space conversion. The data is expected to be read in scan-line multiples. */ v = sp->cinfo.d.max_v_samp_factor/compptr->v_samp_factor; if ( (cc /= compptr->downsampled_width) /* No. of rows in caller's buffer */ > (rows = (sp->cinfo.d.output_height-sp->cinfo.d.output_scanline+v-1)/v) ) cc = rows; /* No. of rows of "clumps" to read */ lines_per_MCU = sp->cinfo.d.max_v_samp_factor# ifdef D_LOSSLESS_SUPPORTED * (size = sp->cinfo.d.min_codec_data_unit);# else * (size = DCTSIZE);# endif L: if (sp->scancount >= size) /* reload downsampled-data buffers */ { if ( CALLJPEG(sp,-1,jpeg_read_raw_data(&sp->cinfo.d,sp->ds_buffer,lines_per_MCU)) != lines_per_MCU ) return 0; sp->scancount = 0; }; rows = 0; do { register JSAMPLE *inptr = sp->ds_buffer[s][sp->scancount*compptr->v_samp_factor + rows]; register int clumps_per_line = compptr->downsampled_width; do *buf++ = *inptr++; while (--clumps_per_line > 0); /* Copy scanline */ tif->tif_row += v; if (--cc <= 0) return 1; /* End of caller's buffer? */ } while (++rows < compptr->v_samp_factor); ++sp->scancount; goto L; }/* "OJPEGSetupDecode()" temporarily forces the JPEG Library to use the following subroutine as a "dummy" input reader in order to fool the library into thinking that it has read the image's first "Start of Scan" (SOS) marker, so that it initializes accordingly.*//*ARGSUSED*/ METHODDEF(int)fake_SOS_marker(j_decompress_ptr cinfo){return JPEG_REACHED_SOS;}/*ARGSUSED*/ METHODDEF(int)suspend(j_decompress_ptr cinfo){return JPEG_SUSPENDED;}/* The JPEG Library's "null" color-space converter actually re-packs separate color planes (it's native image representation) into a pixel-interleaved, contiguous plane. But if our TIFF Library client is tryng to process a PLANARCONFIG_SEPARATE image, we don't want that; so here are modifications of code in the JPEG Library's "jdcolor.c" file, which simply copy Bytes to a color plane specified by the current JPEG "scan".*/METHODDEF(void)ycc_rgb_convert(register j_decompress_ptr cinfo,JSAMPIMAGE in,JDIMENSION row, register JSAMPARRAY out,register int nrows) { typedef struct /* "jdcolor.c" color-space conversion state */ { /* WARNING: This declaration is ugly and dangerous! It's supposed to be private to the JPEG Library's "jdcolor.c" module, but we also need it here. Since the library's copy might change without notice, be sure to keep this one synchronized or the following code will break! */ struct jpeg_color_deconverter pub; /* Public fields */ /* Private state for YCC->RGB conversion */ int *Cr_r_tab, /* ->Cr to R conversion table */ *Cb_b_tab; /* ->Cb to B conversion table */ INT32 *Cr_g_tab, /* ->Cr to G conversion table */ *Cb_g_tab; /* ->Cb to G conversion table */ } *my_cconvert_ptr; my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; JSAMPARRAY irow0p = in[0] + row; register JSAMPLE *range_limit = cinfo->sample_range_limit; register JSAMPROW outp, Y; switch (cinfo->output_scan_number - 1) { JSAMPARRAY irow1p, irow2p; register INT32 *table0, *table1; SHIFT_TEMPS case RGB_RED : irow2p = in[2] + row; table0 = (INT32 *)cconvert->Cr_r_tab; while (--nrows >= 0) { register JSAMPROW Cr = *irow2p++; register int i = cinfo->output_width; Y = *irow0p++; outp = *out++; while (--i >= 0) *outp++ = range_limit[*Y++ + table0[*Cr++]]; }; return; case RGB_GREEN: irow1p = in[1] + row; irow2p = in[2] + row; table0 = cconvert->Cb_g_tab; table1 = cconvert->Cr_g_tab; while (--nrows >= 0) { register JSAMPROW Cb = *irow1p++, Cr = *irow2p++; register int i = cinfo->output_width; Y = *irow0p++; outp = *out++; while (--i >= 0) *outp++ =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -