static bool TIFFjpeg_tables_dest(JPEGState sp, TIFF tif) { // Allocate a working buffer for building tables. // Initial size is 1000 bytes, which is usually adequate. sp.jpegtables_length=1000; try { sp.jpegtables=new byte[sp.jpegtables_length]; } catch { sp.jpegtables_length=0; TIFFErrorExt(sp.tif.tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables"); return false; } ((jpeg_compress)sp.comm).dest=sp.dest; sp.dest.init_destination=tables_init_destination; sp.dest.empty_output_buffer=tables_empty_output_buffer; sp.dest.term_destination=tables_term_destination; return true; }
static bool TIFFjpeg_start_decompress(JPEGState sp) { try { libjpeg.jpeg_start_decompress((jpeg_decompress)sp.comm); } catch { return false; } return true; }
static bool TIFFjpeg_suppress_tables(JPEGState sp, bool suppress) { try { libjpeg.jpeg_suppress_tables((jpeg_compress)sp.comm, suppress); } catch { return false; } return true; }
static byte[][] TIFFjpeg_alloc_sarray(JPEGState sp, uint samplesperrow, uint numrows) { try { return libjpeg.alloc_sarray(sp.comm, samplesperrow, numrows); } catch { return null; } }
static bool TIFFjpeg_start_compress(JPEGState sp, bool write_all_tables) { try { libjpeg.jpeg_start_compress((jpeg_compress)sp.comm, write_all_tables); } catch { return false; } return true; }
static int TIFFjpeg_write_scanlines(JPEGState sp, byte[][] scanlines, int num_lines) { try { return (int)libjpeg.jpeg_write_scanlines((jpeg_compress)sp.comm, scanlines, (uint)num_lines); } catch { return -1; } }
static void unsuppress_huff_table(JPEGState sp, int tblno) { jpeg_compress c=(jpeg_compress)sp.comm; JHUFF_TBL htbl=c.dc_huff_tbl_ptrs[tblno]; if(htbl!=null) htbl.sent_table=false; htbl=c.ac_huff_tbl_ptrs[tblno]; if(htbl!=null) htbl.sent_table=false; }
static CONSUME_INPUT TIFFjpeg_read_header(JPEGState sp, bool require_image) { try { return libjpeg.jpeg_read_header((jpeg_decompress)sp.comm, require_image); } catch { return (CONSUME_INPUT)(-1); } }
static int TIFFjpeg_read_raw_data(JPEGState sp, byte[][][] data, int max_lines) { try { return (int)libjpeg.jpeg_read_raw_data((jpeg_decompress)sp.comm, data, (uint)max_lines); } catch { return -1; } }
static bool TIFFjpeg_destroy(JPEGState sp) { try { var jd = sp.comm as jpeg_decompress; if (jd != null) { libjpeg.jpeg_destroy(jd); } } catch { return false; } return true; }
static bool TIFFjpeg_finish_decompress(JPEGState sp) { try { return libjpeg.jpeg_finish_decompress((jpeg_decompress)sp.comm); } catch { return false; } }
static void TIFFjpeg_data_src(JPEGState sp, TIFF tif) { ((jpeg_decompress)sp.comm).src=sp.src; sp.src.init_source=std_init_source; sp.src.fill_input_buffer=std_fill_input_buffer; sp.src.skip_input_data=std_skip_input_data; sp.src.resync_to_restart=libjpeg.jpeg_resync_to_restart; sp.src.term_source=std_term_source; sp.src.bytes_in_buffer=0; // for safety sp.src.input_bytes=null; sp.src.next_input_byte=0; }
static void TIFFjpeg_data_dest(JPEGState sp, TIFF tif) { ((jpeg_compress)sp.comm).dest=sp.dest; sp.dest.init_destination=std_init_destination; sp.dest.empty_output_buffer=std_empty_output_buffer; sp.dest.term_destination=std_term_destination; }
static bool TIFFjpeg_create_decompress(JPEGState sp) { // initialize JPEG error handling jpeg_decompress d=new jpeg_decompress(); sp.comm=d; sp.comm.err=libjpeg.jpeg_std_error(sp.err); sp.err.error_exit=TIFFjpeg_error_exit; sp.err.output_message=TIFFjpeg_output_message; d.client_data=sp; try { libjpeg.jpeg_create_decompress(d); } catch { return false; } return true; }
static void TIFFjpeg_tables_src(JPEGState sp, TIFF tif) { TIFFjpeg_data_src(sp, tif); sp.src.init_source=tables_init_source; }
static int TIFFjpeg_read_scanlines(JPEGState sp, byte[][] scanlines, int max_lines) { try { return (int)libjpeg.jpeg_read_scanlines((jpeg_decompress)sp.comm, scanlines, (uint)max_lines); } catch { return -1; } }
static int TIFFjpeg_write_raw_data(JPEGState sp, byte[][][] data, int num_lines) { try { return (int)libjpeg.jpeg_write_raw_data((jpeg_compress)sp.comm, data, (uint)num_lines); } catch { return -1; } }
static bool TIFFjpeg_set_colorspace(JPEGState sp, J_COLOR_SPACE colorspace) { try { libjpeg.jpeg_set_colorspace((jpeg_compress)sp.comm, colorspace); } catch { return false; } return true; }
static bool TIFFjpeg_write_tables(JPEGState sp) { try { libjpeg.jpeg_write_tables((jpeg_compress)sp.comm); } catch { return false; } return true; }
static bool TIFFjpeg_set_quality(JPEGState sp, int quality, bool force_baseline) { try { libjpeg.jpeg_set_quality((jpeg_compress)sp.comm, quality, force_baseline); } catch { return false; } return true; }
// JPEG Encoding. static void unsuppress_quant_table(JPEGState sp, int tblno) { jpeg_compress c=(jpeg_compress)sp.comm; JQUANT_TBL qtbl=c.quant_tbl_ptrs[tblno]; if(qtbl!=null) qtbl.sent_table=false; }
static bool TIFFInitJPEG(TIFF tif, COMPRESSION scheme) { #if DEBUG if(scheme!=COMPRESSION.JPEG) throw new Exception("scheme!=COMPRESSION.JPEG"); #endif // Merge codec-specific tag information. if(!_TIFFMergeFieldInfo(tif, jpegFieldInfo)) { TIFFErrorExt(tif.tif_clientdata, "TIFFInitJPEG", "Merging JPEG codec-specific tags failed"); return false; } // Allocate state block so tag methods have storage to record values. JPEGState sp=null; try { tif.tif_data=sp=new JPEGState(); } catch { TIFFErrorExt(tif.tif_clientdata, "TIFFInitJPEG", "No space for JPEG state block"); return false; } sp.tif=tif; // back link // Override parent get/set field methods. sp.vgetparent=tif.tif_tagmethods.vgetfield; tif.tif_tagmethods.vgetfield=JPEGVGetField; // hook for codec tags sp.vsetparent=tif.tif_tagmethods.vsetfield; tif.tif_tagmethods.vsetfield=JPEGVSetField; // hook for codec tags sp.printdir=tif.tif_tagmethods.printdir; tif.tif_tagmethods.printdir=JPEGPrintDir; // hook for codec tags // Default values for codec-specific fields sp.jpegtables=null; sp.jpegtables_length=0; sp.jpegquality=75; // Default IJG quality sp.jpegcolormode=JPEGCOLORMODE.RAW; sp.jpegtablesmode=JPEGTABLESMODE.QUANT|JPEGTABLESMODE.HUFF; sp.recvparams=0; sp.subaddress=null; sp.faxdcs=null; sp.ycbcrsampling_fetched=false; // Install codec methods. tif.tif_setupdecode=JPEGSetupDecode; tif.tif_predecode=JPEGPreDecode; tif.tif_decoderow=JPEGDecode; tif.tif_decodestrip=JPEGDecode; tif.tif_decodetile=JPEGDecode; tif.tif_setupencode=JPEGSetupEncode; tif.tif_preencode=JPEGPreEncode; tif.tif_postencode=JPEGPostEncode; tif.tif_encoderow=JPEGEncode; tif.tif_encodestrip=JPEGEncode; tif.tif_encodetile=JPEGEncode; tif.tif_cleanup=JPEGCleanup; sp.defsparent=tif.tif_defstripsize; tif.tif_defstripsize=JPEGDefaultStripSize; sp.deftparent=tif.tif_deftilesize; tif.tif_deftilesize=JPEGDefaultTileSize; tif.tif_flags|=TIF_FLAGS.TIFF_NOBITREV; // no bit reversal, please sp.cinfo_initialized=false; // Create a JPEGTables field if no directory has yet been created. // We do this just to ensure that sufficient space is reserved for // the JPEGTables field. It will be properly created the right // size later. if(tif.tif_diroff==0) { uint SIZE_OF_JPEGTABLES=2000; // The following line assumes incorrectly that all JPEG-in-TIFF files will have // a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written // when the JPEG data is placed with TIFFWriteRawStrip. The field bit should be // set, anyway, later when actual JPEGTABLES header is generated, so removing it // here hopefully is harmless. //TIFFSetFieldBit(tif, FIELD.JPEG_JPEGTABLES); sp.jpegtables_length=SIZE_OF_JPEGTABLES; sp.jpegtables=new byte[sp.jpegtables_length]; } // Mark the TIFFTAG.YCBCRSAMPLES as present even if it is not // see: JPEGFixupTestSubsampling(). TIFFSetFieldBit(tif, FIELD.YCBCRSUBSAMPLING); return true; }