private bool OJPEGReadBufferFill() { ushort m; int n; /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made * in any other case, seek or read errors should be passed through */ do { if (m_in_buffer_file_togo != 0) { TiffStream stream = m_tif.GetStream(); if (!m_in_buffer_file_pos_log) { stream.Seek(m_tif.m_clientdata, m_in_buffer_file_pos, SeekOrigin.Begin); m_in_buffer_file_pos_log = true; } m = OJPEG_BUFFER; if (m > m_in_buffer_file_togo) m = (ushort)m_in_buffer_file_togo; n = stream.Read(m_tif.m_clientdata, m_in_buffer, 0, (int)m); if (n == 0) return false; Debug.Assert(n > 0); Debug.Assert(n <= OJPEG_BUFFER); Debug.Assert(n < 65536); Debug.Assert((ushort)n <= m_in_buffer_file_togo); m = (ushort)n; m_in_buffer_togo = m; m_in_buffer_cur = 0; m_in_buffer_file_togo -= m; m_in_buffer_file_pos += m; break; } m_in_buffer_file_pos_log = false; switch (m_in_buffer_source) { case OJPEGStateInBufferSource.osibsNotSetYet: if (m_jpeg_interchange_format != 0) { m_in_buffer_file_pos = m_jpeg_interchange_format; m_in_buffer_file_togo = m_jpeg_interchange_format_length; } m_in_buffer_source = OJPEGStateInBufferSource.osibsJpegInterchangeFormat; break; case OJPEGStateInBufferSource.osibsJpegInterchangeFormat: m_in_buffer_source = OJPEGStateInBufferSource.osibsStrile; goto case OJPEGStateInBufferSource.osibsStrile; case OJPEGStateInBufferSource.osibsStrile: if (m_in_buffer_next_strile == m_in_buffer_strile_count) m_in_buffer_source = OJPEGStateInBufferSource.osibsEof; else { if (m_tif.m_dir.td_stripoffset == null) { Tiff.ErrorExt(m_tif, m_tif.m_clientdata, m_tif.m_name, "Strip offsets are missing"); return false; } m_in_buffer_file_pos = m_tif.m_dir.td_stripoffset[m_in_buffer_next_strile]; if (m_in_buffer_file_pos != 0) { if (m_in_buffer_file_pos >= m_file_size) m_in_buffer_file_pos = 0; else { m_in_buffer_file_togo = m_tif.m_dir.td_stripbytecount[m_in_buffer_next_strile]; if (m_in_buffer_file_togo == 0) m_in_buffer_file_pos = 0; else if (m_in_buffer_file_pos + m_in_buffer_file_togo > m_file_size) m_in_buffer_file_togo = m_file_size - m_in_buffer_file_pos; } } m_in_buffer_next_strile++; } break; default: return false; } } while (true); return true; }
private bool OJPEGReadHeaderInfoSec() { const string module = "OJPEGReadHeaderInfoSec"; byte m; ushort n; byte o; if (m_file_size == 0) m_file_size = (uint)m_tif.GetStream().Size(m_tif.m_clientdata); if (m_jpeg_interchange_format != 0) { if (m_jpeg_interchange_format >= m_file_size) { m_jpeg_interchange_format = 0; m_jpeg_interchange_format_length = 0; } else { if ((m_jpeg_interchange_format_length == 0) || (m_jpeg_interchange_format + m_jpeg_interchange_format_length > m_file_size)) m_jpeg_interchange_format_length = m_file_size - m_jpeg_interchange_format; } } m_in_buffer_source = OJPEGStateInBufferSource.osibsNotSetYet; m_in_buffer_next_strile = 0; m_in_buffer_strile_count = (uint)m_tif.m_dir.td_nstrips; m_in_buffer_file_togo = 0; m_in_buffer_togo = 0; do { if (!OJPEGReadBytePeek(out m)) return false; if (m != 255) break; OJPEGReadByteAdvance(); do { if (!OJPEGReadByte(out m)) return false; } while (m == 255); switch ((JpegMarkerType)m) { case JpegMarkerType.SOI: /* this type of marker has no data, and should be skipped */ break; case JpegMarkerType.COM: case JpegMarkerType.APP0: case JpegMarkerType.APP1: case JpegMarkerType.APP2: case JpegMarkerType.APP3: case JpegMarkerType.APP4: case JpegMarkerType.APP5: case JpegMarkerType.APP6: case JpegMarkerType.APP7: case JpegMarkerType.APP8: case JpegMarkerType.APP9: case JpegMarkerType.APP10: case JpegMarkerType.APP11: case JpegMarkerType.APP12: case JpegMarkerType.APP13: case JpegMarkerType.APP14: case JpegMarkerType.APP15: /* this type of marker has data, but it has no use to us (and no place here) and should be skipped */ if (!OJPEGReadWord(out n)) return false; if (n < 2) { if (!m_subsamplingcorrect) Tiff.ErrorExt(m_tif, m_tif.m_clientdata, module, "Corrupt JPEG data"); return false; } if (n > 2) OJPEGReadSkip((ushort)(n - 2)); break; case JpegMarkerType.DRI: if (!OJPEGReadHeaderInfoSecStreamDri()) return false; break; case JpegMarkerType.DQT: if (!OJPEGReadHeaderInfoSecStreamDqt()) return false; break; case JpegMarkerType.DHT: if (!OJPEGReadHeaderInfoSecStreamDht()) return false; break; case JpegMarkerType.SOF0: case JpegMarkerType.SOF1: case JpegMarkerType.SOF3: if (!OJPEGReadHeaderInfoSecStreamSof(m)) return false; if (m_subsamplingcorrect) return true; break; case JpegMarkerType.SOS: if (m_subsamplingcorrect) return true; Debug.Assert(m_plane_sample_offset == 0); if (!OJPEGReadHeaderInfoSecStreamSos()) return false; break; default: Tiff.ErrorExt(m_tif, m_tif.m_clientdata, module, "Unknown marker type {0} in JPEG data", m); return false; } } while (m != (byte)JpegMarkerType.SOS); if (m_subsamplingcorrect) return true; if (!m_sof_log) { if (!OJPEGReadHeaderInfoSecTablesQTable()) return false; m_sof_marker_id = (byte)JpegMarkerType.SOF0; for (o = 0; o < m_samples_per_pixel; o++) m_sof_c[o] = o; m_sof_hv[0] = (byte)((m_subsampling_hor << 4) | m_subsampling_ver); for (o = 1; o < m_samples_per_pixel; o++) m_sof_hv[o] = 17; m_sof_x = m_strile_width; m_sof_y = m_strile_length_total; m_sof_log = true; if (!OJPEGReadHeaderInfoSecTablesDcTable()) return false; if (!OJPEGReadHeaderInfoSecTablesAcTable()) return false; for (o = 1; o < m_samples_per_pixel; o++) m_sos_cs[o] = o; } return true; }
private bool OJPEGPreDecode(short s) { uint m; if (!m_subsamplingcorrect_done) OJPEGSubsamplingCorrect(); if (!m_readheader_done) { if (!OJPEGReadHeaderInfo()) return false; } if (!m_sos_end[s].m_log) { if (!OJPEGReadSecondarySos(s)) return false; } if (m_tif.IsTiled()) m = (uint)m_tif.m_curtile; else m = (uint)m_tif.m_curstrip; if (m_writeheader_done && ((m_write_cursample != s) || (m_write_curstrile > m))) { if (m_libjpeg_session_active) OJPEGLibjpegSessionAbort(); m_writeheader_done = false; } if (!m_writeheader_done) { m_plane_sample_offset = (byte)s; m_write_cursample = s; m_write_curstrile = (uint)(s * m_tif.m_dir.td_stripsperimage); if (!m_in_buffer_file_pos_log || (m_in_buffer_file_pos - m_in_buffer_togo != m_sos_end[s].m_in_buffer_file_pos)) { m_in_buffer_source = m_sos_end[s].m_in_buffer_source; m_in_buffer_next_strile = m_sos_end[s].m_in_buffer_next_strile; m_in_buffer_file_pos = m_sos_end[s].m_in_buffer_file_pos; m_in_buffer_file_pos_log = false; m_in_buffer_file_togo = m_sos_end[s].m_in_buffer_file_togo; m_in_buffer_togo = 0; m_in_buffer_cur = 0; } if (!OJPEGWriteHeaderInfo()) return false; } while (m_write_curstrile < m) { if (m_libjpeg_jpeg_query_style == 0) { if (!OJPEGPreDecodeSkipRaw()) return false; } else { if (!OJPEGPreDecodeSkipScanlines()) return false; } m_write_curstrile++; } return true; }
private bool OJPEGReadSecondarySos(short s) { Debug.Assert(s > 0); Debug.Assert(s < 3); Debug.Assert(m_sos_end[0].m_log); Debug.Assert(!m_sos_end[s].m_log); m_plane_sample_offset = (byte)(s - 1); while (!m_sos_end[m_plane_sample_offset].m_log) m_plane_sample_offset--; m_in_buffer_source = m_sos_end[m_plane_sample_offset].m_in_buffer_source; m_in_buffer_next_strile = m_sos_end[m_plane_sample_offset].m_in_buffer_next_strile; m_in_buffer_file_pos = m_sos_end[m_plane_sample_offset].m_in_buffer_file_pos; m_in_buffer_file_pos_log = false; m_in_buffer_file_togo = m_sos_end[m_plane_sample_offset].m_in_buffer_file_togo; m_in_buffer_togo = 0; m_in_buffer_cur = 0; while (m_plane_sample_offset < s) { do { byte m; if (!OJPEGReadByte(out m)) return false; if (m == 255) { do { if (!OJPEGReadByte(out m)) return false; if (m != 255) break; } while (true); if (m == (byte)JpegMarkerType.SOS) break; } } while (true); m_plane_sample_offset++; if (!OJPEGReadHeaderInfoSecStreamSos()) return false; m_sos_end[m_plane_sample_offset].m_log = true; m_sos_end[m_plane_sample_offset].m_in_buffer_source = m_in_buffer_source; m_sos_end[m_plane_sample_offset].m_in_buffer_next_strile = m_in_buffer_next_strile; m_sos_end[m_plane_sample_offset].m_in_buffer_file_pos = m_in_buffer_file_pos - m_in_buffer_togo; m_sos_end[m_plane_sample_offset].m_in_buffer_file_togo = m_in_buffer_file_togo + m_in_buffer_togo; } return true; }
private void cleanState() { m_jpeg_interchange_format = 0; m_jpeg_interchange_format_length = 0; m_jpeg_proc = 0; m_subsamplingcorrect_done = false; m_subsampling_tag = false; m_subsampling_hor = 0; m_subsampling_ver = 0; m_qtable_offset_count = 0; m_dctable_offset_count = 0; m_actable_offset_count = 0; m_qtable_offset = new uint[3]; m_dctable_offset = new uint[3]; m_actable_offset = new uint[3]; m_restart_interval = 0; m_libjpeg_jpeg_decompress_struct = null; m_file_size = 0; m_image_width = 0; m_image_length = 0; m_strile_width = 0; m_strile_length = 0; m_strile_length_total = 0; m_samples_per_pixel = 0; m_plane_sample_offset = 0; m_samples_per_pixel_per_plane = 0; m_subsamplingcorrect = false; m_subsampling_force_desubsampling_inside_decompression = false; m_qtable = new byte[4][]; m_dctable = new byte[4][]; m_actable = new byte[4][]; m_restart_index = 0; m_sof_log = false; m_sof_marker_id = 0; m_sof_x = 0; m_sof_y = 0; m_sof_c = new byte[3]; m_sof_hv = new byte[3]; m_sof_tq = new byte[3]; m_sos_cs = new byte[3]; m_sos_tda = new byte[3]; m_sos_end = new SosEnd[3]; m_readheader_done = false; m_writeheader_done = false; m_write_cursample = 0; m_write_curstrile = 0; m_libjpeg_session_active = false; m_libjpeg_jpeg_query_style = 0; m_libjpeg_jpeg_error_mgr = null; m_libjpeg_jpeg_source_mgr = null; m_subsampling_convert_log = false; m_subsampling_convert_ylinelen = 0; m_subsampling_convert_ylines = 0; m_subsampling_convert_clinelen = 0; m_subsampling_convert_clines = 0; m_subsampling_convert_ybuf = null; m_subsampling_convert_cbbuf = null; m_subsampling_convert_crbuf = null; m_subsampling_convert_ycbcrimage = null; m_subsampling_convert_clinelenout = 0; m_subsampling_convert_state = 0; m_bytes_per_line = 0; m_lines_per_strile = 0; m_in_buffer_source = OJPEGStateInBufferSource.osibsNotSetYet; m_in_buffer_next_strile = 0; m_in_buffer_strile_count = 0; m_in_buffer_file_pos = 0; m_in_buffer_file_pos_log = false; m_in_buffer_file_togo = 0; m_in_buffer_togo = 0; m_in_buffer_cur = 0; // index into m_in_buffer m_in_buffer = new byte[OJPEG_BUFFER]; m_out_state = 0; m_out_buffer = new byte[OJPEG_BUFFER]; m_skip_buffer = null; m_forceProcessedRgbOutput = false; }