1
0

JpegImage.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "JpegImage.h"
  2. namespace Image {
  3. const static JOCTET EOI_BUFFER[1] = { JPEG_EOI };
  4. JpegImage::JpegImage()
  5. {
  6. }
  7. void JpegImage::SetImageData(const std::string& data)
  8. {
  9. DecompressImage(data.c_str(), data.size());
  10. }
  11. unsigned int JpegImage::Width() const
  12. {
  13. return m_width;
  14. }
  15. unsigned int JpegImage::Height() const
  16. {
  17. return m_height;
  18. }
  19. unsigned int JpegImage::StrideX() const
  20. {
  21. return m_strideX;
  22. }
  23. unsigned int JpegImage::StrideY() const
  24. {
  25. return m_strideY;
  26. }
  27. const std::vector<char>& JpegImage::Data() const
  28. {
  29. return m_data;
  30. }
  31. void JpegImage::InitSource(j_decompress_ptr pCinfo)
  32. {
  33. }
  34. boolean JpegImage::FillInputBuffer(j_decompress_ptr pCinfo)
  35. {
  36. SourceMgrPtr pSrc = reinterpret_cast<SourceMgrPtr>(pCinfo->src);
  37. pSrc->pub.next_input_byte = EOI_BUFFER;
  38. pSrc->pub.bytes_in_buffer = 1;
  39. return TRUE;
  40. }
  41. void JpegImage::SkipInputData(j_decompress_ptr pCinfo, long numBytes)
  42. {
  43. SourceMgrPtr pSrc = reinterpret_cast<SourceMgrPtr>(pCinfo->src);
  44. if (pSrc->pub.bytes_in_buffer < static_cast<size_t>(numBytes))
  45. {
  46. pSrc->pub.next_input_byte = EOI_BUFFER;
  47. pSrc->pub.bytes_in_buffer = 1;
  48. }
  49. else
  50. {
  51. pSrc->pub.next_input_byte += numBytes;
  52. pSrc->pub.bytes_in_buffer -= numBytes;
  53. }
  54. }
  55. void JpegImage::TermSource(j_decompress_ptr pCinfo)
  56. {
  57. }
  58. void JpegImage::SetSourceMgr(j_decompress_ptr pCinfo, const char* pData, size_t len) const
  59. {
  60. SourceMgrPtr pSrc;
  61. if (pCinfo->src == 0)
  62. pCinfo->src = (struct jpeg_source_mgr *)(*pCinfo->mem->alloc_small)(reinterpret_cast<j_common_ptr>(pCinfo), JPOOL_PERMANENT, sizeof(SourceMgr));
  63. pSrc = reinterpret_cast<SourceMgrPtr>(pCinfo->src);
  64. pSrc->pub.init_source = JpegImage::InitSource;
  65. pSrc->pub.fill_input_buffer = JpegImage::FillInputBuffer;
  66. pSrc->pub.skip_input_data = JpegImage::SkipInputData;
  67. pSrc->pub.resync_to_restart = jpeg_resync_to_restart;
  68. pSrc->pub.term_source = JpegImage::TermSource;
  69. pSrc->data = (const JOCTET *)pData;
  70. pSrc->len = len;
  71. pSrc->pub.bytes_in_buffer = len;
  72. pSrc->pub.next_input_byte = pSrc->data;
  73. }
  74. void JpegImage::DecompressImage(const char* pData, size_t len)
  75. {
  76. struct jpeg_decompress_struct cinfo;
  77. struct jpeg_error_mgr jerr;
  78. jerr.trace_level = 0;
  79. cinfo.err = jpeg_std_error(&jerr);
  80. jpeg_create_decompress(&cinfo);
  81. SetSourceMgr(&cinfo, pData, len);
  82. jpeg_read_header(&cinfo, TRUE);
  83. jpeg_start_decompress(&cinfo);
  84. m_width = cinfo.image_width;
  85. m_height = cinfo.image_height;
  86. m_strideX = cinfo.num_components;
  87. m_strideY = m_width * cinfo.num_components;
  88. m_data.resize(m_height * m_strideY);
  89. JSAMPROW scanlines[1];
  90. while (cinfo.output_scanline < cinfo.image_height)
  91. {
  92. scanlines[0] = reinterpret_cast<JSAMPROW>(&m_data[cinfo.output_scanline * m_strideY]);
  93. jpeg_read_scanlines(&cinfo, scanlines, 1);
  94. }
  95. jpeg_finish_decompress(&cinfo);
  96. jpeg_destroy_decompress(&cinfo);
  97. }
  98. } // namespace Image