static FX_BOOL _JpegLoadInfo(FX_LPCBYTE src_buf, FX_DWORD src_size, int& width, int& height, int& num_components, int& bits_per_components, FX_BOOL& color_transform, FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length) { _JpegScanSOI(src_buf, src_size); struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; jerr.error_exit = _error_fatal; jerr.emit_message = _error_do_nothing1; jerr.output_message = _error_do_nothing; jerr.format_message = _error_do_nothing2; jerr.reset_error_mgr = _error_do_nothing; jerr.trace_level = 0; cinfo.err = &jerr; jmp_buf mark; cinfo.client_data = &mark; if (setjmp(mark) == -1) { return FALSE; } jpeg_create_decompress(&cinfo); struct jpeg_source_mgr src; src.init_source = _src_do_nothing; src.term_source = _src_do_nothing; src.skip_input_data = _src_skip_data; src.fill_input_buffer = _src_fill_buffer; src.resync_to_restart = _src_resync; src.bytes_in_buffer = src_size; src.next_input_byte = src_buf; cinfo.src = &src; if (setjmp(mark) == -1) { jpeg_destroy_decompress(&cinfo); return FALSE; } if(icc_buf_ptr && icc_length) { jpeg_save_markers(&cinfo, JPEG_MARKER_ICC, JPEG_MARKER_MAXSIZE); } int ret = jpeg_read_header(&cinfo, TRUE); if (ret != JPEG_HEADER_OK) { jpeg_destroy_decompress(&cinfo); return FALSE; } width = cinfo.image_width; height = cinfo.image_height; num_components = cinfo.num_components; color_transform = cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_space == JCS_YCCK; bits_per_components = cinfo.data_precision; if(icc_buf_ptr != NULL) { *icc_buf_ptr = NULL; } if(icc_length != NULL) { *icc_length = 0; } jpeg_destroy_decompress(&cinfo); return TRUE; }
FX_BOOL CCodec_JpegDecoder::Create(const uint8_t* src_buf, FX_DWORD src_size, int width, int height, int nComps, FX_BOOL ColorTransform, IFX_JpegProvider* pJP) { if (pJP) { m_pExtProvider = pJP; m_pExtContext = m_pExtProvider->CreateDecoder( src_buf, src_size, width, height, nComps, ColorTransform); return m_pExtContext != NULL; } _JpegScanSOI(src_buf, src_size); m_SrcBuf = src_buf; m_SrcSize = src_size; jerr.error_exit = _error_fatal; jerr.emit_message = _error_do_nothing1; jerr.output_message = _error_do_nothing; jerr.format_message = _error_do_nothing2; jerr.reset_error_mgr = _error_do_nothing; src.init_source = _src_do_nothing; src.term_source = _src_do_nothing; src.skip_input_data = _src_skip_data; src.fill_input_buffer = _src_fill_buffer; src.resync_to_restart = _src_resync; m_bJpegTransform = ColorTransform; if (src_size > 1 && FXSYS_memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0) { ((uint8_t*)src_buf)[src_size - 2] = 0xFF; ((uint8_t*)src_buf)[src_size - 1] = 0xD9; } m_OutputWidth = m_OrigWidth = width; m_OutputHeight = m_OrigHeight = height; if (!InitDecode()) { return FALSE; } if (cinfo.num_components < nComps) { return FALSE; } if ((int)cinfo.image_width < width) { return FALSE; } m_Pitch = (cinfo.image_width * cinfo.num_components + 3) / 4 * 4; m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); m_nComps = cinfo.num_components; m_bpc = 8; m_bColorTransformed = FALSE; m_bStarted = FALSE; return TRUE; }