?? tif_jpeg.c
字號(hào):
int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) return (0); sp->scancount = 0; } /* * Fastest way to unseparate data is to make one pass * over the scanline for each row of each component. */ clumpoffset = 0; /* first sample in clump */ for (ci = 0, compptr = sp->cinfo.d.comp_info; ci < sp->cinfo.d.num_components; ci++, compptr++) { int hsamp = compptr->h_samp_factor; int vsamp = compptr->v_samp_factor; int ypos; for (ypos = 0; ypos < vsamp; ypos++) { JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];#ifdef JPEG_LIB_MK1 JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;#else JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;#endif JDIMENSION nclump; if (hsamp == 1) { /* fast path for at least Cb and Cr */ for (nclump = clumps_per_line; nclump-- > 0; ) { outptr[0] = *inptr++; outptr += samples_per_clump; } } else { int xpos; /* general case */ for (nclump = clumps_per_line; nclump-- > 0; ) { for (xpos = 0; xpos < hsamp; xpos++) outptr[xpos] = *inptr++; outptr += samples_per_clump; } } clumpoffset += hsamp; } }#ifdef JPEG_LIB_MK1 { if (sp->cinfo.d.data_precision == 8) { int i=0; int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components; for (i=0; i<len; i++) { ((unsigned char*)buf)[i] = tmpbuf[i] & 0xff; } } else { // 12-bit int value_pairs = (sp->cinfo.d.output_width * sp->cinfo.d.num_components) / 2; int iPair; for( iPair = 0; iPair < value_pairs; iPair++ ) { unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3; JSAMPLE *in_ptr = tmpbuf + iPair * 2; out_ptr[0] = (in_ptr[0] & 0xff0) >> 4; out_ptr[1] = ((in_ptr[0] & 0xf) << 4) | ((in_ptr[1] & 0xf00) >> 8); out_ptr[2] = ((in_ptr[1] & 0xff) >> 0); } } }#endif sp->scancount ++; tif->tif_row += sp->v_sampling; /* increment/decrement of buf and cc is still incorrect, but should not matter * TODO: resolve this */ buf += sp->bytesperline; cc -= sp->bytesperline; nrows -= sp->v_sampling; } while (nrows > 0);#ifdef JPEG_LIB_MK1 _TIFFfree(tmpbuf);#endif } /* Close down the decompressor if done. */ return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || TIFFjpeg_finish_decompress(sp);}/* * JPEG Encoding. */static voidunsuppress_quant_table (JPEGState* sp, int tblno){ JQUANT_TBL* qtbl; if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) qtbl->sent_table = FALSE;}static voidunsuppress_huff_table (JPEGState* sp, int tblno){ JHUFF_TBL* htbl; if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) htbl->sent_table = FALSE; if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) htbl->sent_table = FALSE;}static intprepare_JPEGTables(TIFF* tif){ JPEGState* sp = JState(tif); JPEGInitializeLibJPEG( tif, 0, 0 ); /* Initialize quant tables for current quality setting */ if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) return (0); /* Mark only the tables we want for output */ /* NB: chrominance tables are currently used only with YCbCr */ if (!TIFFjpeg_suppress_tables(sp, TRUE)) return (0); if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { unsuppress_quant_table(sp, 0); if (sp->photometric == PHOTOMETRIC_YCBCR) unsuppress_quant_table(sp, 1); } if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) { unsuppress_huff_table(sp, 0); if (sp->photometric == PHOTOMETRIC_YCBCR) unsuppress_huff_table(sp, 1); } /* Direct libjpeg output into jpegtables */ if (!TIFFjpeg_tables_dest(sp, tif)) return (0); /* Emit tables-only datastream */ if (!TIFFjpeg_write_tables(sp)) return (0); return (1);}static intJPEGSetupEncode(TIFF* tif){ JPEGState* sp = JState(tif); TIFFDirectory *td = &tif->tif_dir; static const char module[] = "JPEGSetupEncode"; JPEGInitializeLibJPEG( tif, 1, 0 ); assert(sp != NULL); assert(!sp->cinfo.comm.is_decompressor); /* * Initialize all JPEG parameters to default values. * Note that jpeg_set_defaults needs legal values for * in_color_space and input_components. */ sp->cinfo.c.in_color_space = JCS_UNKNOWN; sp->cinfo.c.input_components = 1; if (!TIFFjpeg_set_defaults(sp)) return (0); /* Set per-file parameters */ sp->photometric = td->td_photometric; switch (sp->photometric) { case PHOTOMETRIC_YCBCR: sp->h_sampling = td->td_ycbcrsubsampling[0]; sp->v_sampling = td->td_ycbcrsubsampling[1]; /* * A ReferenceBlackWhite field *must* be present since the * default value is inappropriate for YCbCr. Fill in the * proper value if application didn't set it. */ { float *ref; if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref)) { float refbw[6]; long top = 1L << td->td_bitspersample; refbw[0] = 0; refbw[1] = (float)(top-1L); refbw[2] = (float)(top>>1); refbw[3] = refbw[1]; refbw[4] = refbw[2]; refbw[5] = refbw[1]; TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); } } break; case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ case PHOTOMETRIC_MASK: TIFFErrorExt(tif->tif_clientdata, module, "PhotometricInterpretation %d not allowed for JPEG", (int) sp->photometric); return (0); default: /* TIFF 6.0 forbids subsampling of all other color spaces */ sp->h_sampling = 1; sp->v_sampling = 1; break; } /* Verify miscellaneous parameters */ /* * This would need work if libtiff ever supports different * depths for different components, or if libjpeg ever supports * run-time selection of depth. Neither is imminent. */#ifdef JPEG_LIB_MK1 /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ if (td->td_bitspersample != 8 && td->td_bitspersample != 12) #else if (td->td_bitspersample != BITS_IN_JSAMPLE )#endif { TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG", (int) td->td_bitspersample); return (0); } sp->cinfo.c.data_precision = td->td_bitspersample;#ifdef JPEG_LIB_MK1 sp->cinfo.c.bits_in_jsample = td->td_bitspersample;#endif if (isTiled(tif)) { if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { TIFFErrorExt(tif->tif_clientdata, module, "JPEG tile height must be multiple of %d", sp->v_sampling * DCTSIZE); return (0); } if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { TIFFErrorExt(tif->tif_clientdata, module, "JPEG tile width must be multiple of %d", sp->h_sampling * DCTSIZE); return (0); } } else { if (td->td_rowsperstrip < td->td_imagelength && (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { TIFFErrorExt(tif->tif_clientdata, module, "RowsPerStrip must be multiple of %d for JPEG", sp->v_sampling * DCTSIZE); return (0); } } /* Create a JPEGTables field if appropriate */ if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) { if (!prepare_JPEGTables(tif)) return (0); /* Mark the field present */ /* Can't use TIFFSetField since BEENWRITING is already set! */ TIFFSetFieldBit(tif, FIELD_JPEGTABLES); tif->tif_flags |= TIFF_DIRTYDIRECT; } else { /* We do not support application-supplied JPEGTables, */ /* so mark the field not present */ TIFFClrFieldBit(tif, FIELD_JPEGTABLES); } /* Direct libjpeg output to libtiff's output buffer */ TIFFjpeg_data_dest(sp, tif); return (1);}/* * Set encoding state at the start of a strip or tile. */static intJPEGPreEncode(TIFF* tif, tsample_t s){ JPEGState *sp = JState(tif); TIFFDirectory *td = &tif->tif_dir; static const char module[] = "JPEGPreEncode"; uint32 segment_width, segment_height; int downsampled_input; assert(sp != NULL); assert(!sp->cinfo.comm.is_decompressor); /* * Set encoding parameters for this strip/tile. */ if (isTiled(tif)) { segment_width = td->td_tilewidth; segment_height = td->td_tilelength; sp->bytesperline = TIFFTileRowSize(tif); } else { segment_width = td->td_imagewidth; segment_height = td->td_imagelength - tif->tif_row; if (segment_height > td->td_rowsperstrip) segment_height = td->td_rowsperstrip; sp->bytesperline = TIFFOldScanlineSize(tif); } if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { /* for PC 2, scale down the strip/tile size * to match a downsampled component */ segment_width = TIFFhowmany(segment_width, sp->h_sampling); segment_height = TIFFhowmany(segment_height, sp->v_sampling); } if (segment_width > 65535 || segment_height > 65535) { TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG"); return (0); } sp->cinfo.c.image_width = segment_width; sp->cinfo.c.image_height = segment_height; downsampled_input = FALSE; if (td->td_planarconfig == PLANARCONFIG_CONTIG) { sp->cinfo.c.input_components = td->td_samplesperpixel; if (sp->photometric == PHOTOMETRIC_YCBCR) { if (sp->jpegcolormode == JPEGCOLORMODE_RGB) { sp->cinfo.c.in_color_space = JCS_RGB; } else { sp->cinfo.c.in_color_space = JCS_YCbCr; if (sp->h_sampling != 1 || sp->v_sampling != 1) downsampled_input = TRUE; } if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) return (0); /* * Set Y sampling factors; * we assume jpeg_set_colorspace() set the rest to 1 */ sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; } else { sp->cinfo.c.in_color_space = JCS_UNKNOWN; if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) return (0); /* jpeg_set_colorspace set all sampling factors to 1 */ } } else { sp->cinfo.c.input_components = 1; sp->cinfo.c.in_color_space = JCS_UNKNOWN; if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) return (0); sp->cinfo.c.comp_info[0].component_id = s; /* jpeg_set_colorspace() set sampling factors to 1 */ if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { sp->cinfo.c.comp_info[0].quant_tbl_no = 1; sp->cinfo.c.comp_info[0].dc_tbl_no = 1; sp->cinfo.c.comp_info[0].ac_tbl_no = 1; } } /* ensure libjpeg won't write any extraneous markers */ sp->cinfo.c.write_JFIF_header = FALSE; sp->cinfo.c.write_Adobe_marker = FALSE; /* set up table handling correctly */ if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) { if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) return (0); unsuppress_quant_table(sp, 0); unsuppress_quant_table(sp, 1); } if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) sp->cinfo.c.optimize_coding = FALSE; else sp->cinfo.c.optimize_coding = TRUE; if (downsampled_input) { /* Need to use raw-data interface to libjpeg */ sp->cinfo.c.raw_data_in = TRUE; tif->tif_encoderow = JPEGEncodeRaw; tif->tif_encodestrip = JPEGEncodeRaw; tif->tif_encodetile = JPEGEncodeRaw; } else { /* Use normal interface to libjpeg */ sp->cinfo.c.raw_data_in = FALSE; tif->tif_encoderow = JPEGEncode; tif->tif_encodestrip = JPEGEncode; tif->tif_encodetile = JPEGEncode; } /* Start JPEG compressor */ if (!TIFFjpeg_start_compress(sp, FALSE)) return (0); /* Allocate downsampled-data buffers if needed */ if (downsampled_input) { if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, sp->cinfo.c.num_components)) return (0); } sp->scancount = 0; return (1);}/* * Encode a chunk of pixels. * "Standard" case: incoming data is not downsampled. */static intJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s){ JPEGState *sp = JState(tif); tsize_t nrows; JSAMPROW bufptr[1]; (void) s; assert(sp != NULL); /* data is expected to be supplied in multiples of a scanline */ nrows = cc / sp->bytesperline; if (cc % sp->bytesperline) TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded"); while (nrows-- > 0) { bufptr[0] = (JSAMPROW) buf; if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) return (0); if (nrows > 0) tif->tif_row++; buf += sp->bytesperline; } return (1);}/* * Encode a chunk of pixels. * Incoming data is expected to be downsampled per sampling factors. */static intJPEGEncodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s){ JPEGState *sp = JState(tif); JSAMPLE* inptr; JSAMPLE* outptr; tsize_t nrows; JDIMENSION clumps_per_line, nclump; int clumpoffset, ci, xpos, ypos; jpeg_component_info* compptr; int samples_per_clump = sp->samplesperclump; tsize_t bytesperclumpline; (void) s; assert(sp != NULL); /* data is expected to be supplied in multiples of a clumpline */ /* a clumpline is equivalent to v_sampling desubsampled scanlines */ /* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */ bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling) *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7) /8; nrows = ( cc / bytesperclumpline ) * sp->v_sampling; if (cc % bytesperclumpline) TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded"); /* Cb,Cr both have sampling factors 1, so this is correct */ clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; while (nrows > 0) { /* * Fastest way to separate the data is to make one pass * over the scanline for each row of each component. */ clumpoffset = 0; /* first sample in clump */ for (ci = 0, compptr = sp->cinfo.c.comp_info; ci < sp->cinfo.c.num_components; ci++, compptr++) { int hsamp = compptr->h_samp_factor; int vsamp = compptr->v_samp_factor; int padding = (int) (compptr->width_in_blocks * DCTSIZE - clumps_per_line * hsamp); for (ypos = 0; ypos < vsamp; ypos++) { inptr = ((JSAMPLE*) buf) + clumpoffset; outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; if (hsamp == 1) { /* fast path for at least Cb and Cr */ for (nclump = clumps_per_line; nclump-- > 0; ) { *outptr++ = inptr[0]; inptr += samples_per_clump; } } else { /* general case */ for (nclump = clumps_per_line; nclump-- > 0; ) { for (xpos = 0; xpos < hsamp; xpos++) *outptr++ = inptr[xpos]; inptr += samples_per_clump; } } /* pad each scanline as needed */ for (xpos = 0; xpos < padding; xpos++) { *outptr = outptr[-1]; outptr++; } clumpoffset += hsamp; } } sp->scancount++; if (sp->scancount >= DCTSIZE) { int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -