#include "JpegImage.h" namespace Image { const static JOCTET EOI_BUFFER[1] = { JPEG_EOI }; JpegImage::JpegImage() { } void JpegImage::SetImageData(const std::string& data) { DecompressImage(data.c_str(), data.size()); } unsigned int JpegImage::Width() const { return m_width; } unsigned int JpegImage::Height() const { return m_height; } unsigned int JpegImage::StrideX() const { return m_strideX; } unsigned int JpegImage::StrideY() const { return m_strideY; } const std::vector& JpegImage::Data() const { return m_data; } void JpegImage::InitSource(j_decompress_ptr pCinfo) { } boolean JpegImage::FillInputBuffer(j_decompress_ptr pCinfo) { SourceMgrPtr pSrc = reinterpret_cast(pCinfo->src); pSrc->pub.next_input_byte = EOI_BUFFER; pSrc->pub.bytes_in_buffer = 1; return TRUE; } void JpegImage::SkipInputData(j_decompress_ptr pCinfo, long numBytes) { SourceMgrPtr pSrc = reinterpret_cast(pCinfo->src); if (pSrc->pub.bytes_in_buffer < static_cast(numBytes)) { pSrc->pub.next_input_byte = EOI_BUFFER; pSrc->pub.bytes_in_buffer = 1; } else { pSrc->pub.next_input_byte += numBytes; pSrc->pub.bytes_in_buffer -= numBytes; } } void JpegImage::TermSource(j_decompress_ptr pCinfo) { } void JpegImage::SetSourceMgr(j_decompress_ptr pCinfo, const char* pData, size_t len) const { SourceMgrPtr pSrc; if (pCinfo->src == 0) pCinfo->src = (struct jpeg_source_mgr *)(*pCinfo->mem->alloc_small)(reinterpret_cast(pCinfo), JPOOL_PERMANENT, sizeof(SourceMgr)); pSrc = reinterpret_cast(pCinfo->src); pSrc->pub.init_source = JpegImage::InitSource; pSrc->pub.fill_input_buffer = JpegImage::FillInputBuffer; pSrc->pub.skip_input_data = JpegImage::SkipInputData; pSrc->pub.resync_to_restart = jpeg_resync_to_restart; pSrc->pub.term_source = JpegImage::TermSource; pSrc->data = (const JOCTET *)pData; pSrc->len = len; pSrc->pub.bytes_in_buffer = len; pSrc->pub.next_input_byte = pSrc->data; } void JpegImage::DecompressImage(const char* pData, size_t len) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; jerr.trace_level = 0; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); SetSourceMgr(&cinfo, pData, len); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); m_width = cinfo.image_width; m_height = cinfo.image_height; m_strideX = cinfo.num_components; m_strideY = m_width * cinfo.num_components; m_data.resize(m_height * m_strideY); JSAMPROW scanlines[1]; while (cinfo.output_scanline < cinfo.image_height) { scanlines[0] = reinterpret_cast(&m_data[cinfo.output_scanline * m_strideY]); jpeg_read_scanlines(&cinfo, scanlines, 1); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); } } // namespace Image