From 87631cdf588c2a9389cc911ffe6a9bf49b5b2cf9 Mon Sep 17 00:00:00 2001 From: Kulikova Svetlana Date: Tue, 23 Mar 2021 10:57:07 +0300 Subject: [PATCH] add jpeg2000 support --- DesktopEditor/cximage/CxImage/ximacfg.h | 6 +- DesktopEditor/graphics/pro/js/make.py | 31 +++- .../graphics/pro/js/qt/test/main.cpp | 2 +- DesktopEditor/raster/BgraFrame.cpp | 28 +-- DesktopEditor/raster/Jp2/J2kFile.cpp | 162 +++++++++++++++++ DesktopEditor/raster/Jp2/J2kFile.h | 1 + DesktopEditor/raster/Jp2/J2kIncludes.h | 165 +++++++++++++++++- DesktopEditor/raster/Jp2/Jp2.h | 4 +- 8 files changed, 375 insertions(+), 24 deletions(-) diff --git a/DesktopEditor/cximage/CxImage/ximacfg.h b/DesktopEditor/cximage/CxImage/ximacfg.h index 418ac78b87..5c16f1faeb 100644 --- a/DesktopEditor/cximage/CxImage/ximacfg.h +++ b/DesktopEditor/cximage/CxImage/ximacfg.h @@ -34,7 +34,7 @@ #define CXIMAGE_SUPPORT_WBMP 0 #define CXIMAGE_SUPPORT_WMF 0 -#define CXIMAGE_SUPPORT_JP2 0 +#define CXIMAGE_SUPPORT_JP2 1 #define CXIMAGE_SUPPORT_JPC 0 #define CXIMAGE_SUPPORT_PGX 0 #define CXIMAGE_SUPPORT_PNM 0 @@ -83,11 +83,7 @@ #define CXIMAGE_ERR_NOFILE "null file handler" #define CXIMAGE_ERR_NOIMAGE "null image!!!" -#if defined(BUILDING_WASM_MODULE) -#define CXIMAGE_SUPPORT_EXCEPTION_HANDLING 0 -#else #define CXIMAGE_SUPPORT_EXCEPTION_HANDLING 1 -#endif // BUILDING_WASM_MODULE ///////////////////////////////////////////////////////////////////////////// //color to grey mapping diff --git a/DesktopEditor/graphics/pro/js/make.py b/DesktopEditor/graphics/pro/js/make.py index a613cf4e22..5c947d8699 100644 --- a/DesktopEditor/graphics/pro/js/make.py +++ b/DesktopEditor/graphics/pro/js/make.py @@ -22,7 +22,6 @@ if not base.is_dir("emsdk"): # compile compiler_flags = ["-o raster.js", "-O3", - "-fno-exceptions", "-fno-rtti", "-s WASM=1", "-s ALLOW_MEMORY_GROWTH=1", @@ -53,7 +52,7 @@ libCxImage_src_path = "./../../../cximage/CxImage" input_cximage_sources = ["ximaenc.cpp", "ximaexif.cpp", "ximage.cpp", "ximainfo.cpp", "ximajpg.cpp", "ximalpha.cpp", "ximapal.cpp", "ximasel.cpp", "xmemfile.cpp", "ximapng.cpp", "ximabmp.cpp", "ximatran.cpp", - "ximatif.cpp", "tif_xfile.cpp"] + "ximatif.cpp", "tif_xfile.cpp", "ximajas.cpp"] libJpeg_src_path = "./../../../cximage/jpeg" input_jpeg_sources = ["jerror.c", "jdmarker.c", "jdapimin.c", "jdmaster.c", "jdapistd.c", @@ -79,6 +78,25 @@ input_tiff_sources = ["tif_close.c", "tif_dir.c", "tif_aux.c", "tif_getimage.c", "tif_jpeg.c", "tif_next.c", "tif_thunder.c", "tif_packbits.c", "tif_lzw.c", "tif_zip.c", "tif_fax3sm.c", "tif_predict.c"] +libJasper_src_path = "./../../../cximage/jasper" +input_jasper_sources = ["base/jas_init.c", "base/jas_stream.c", "base/jas_malloc.c", + "base/jas_image.c", "base/jas_cm.c", "base/jas_seq.c", + "base/jas_string.c", "base/jas_icc.c", "base/jas_debug.c", + "base/jas_iccdata.c", "base/jas_tvp.c", "base/jas_version.c", + "mif/mif_cod.c", "pnm/pnm_dec.c", "pnm/pnm_enc.c", "pnm/pnm_cod.c", + "bmp/bmp_dec.c", "bmp/bmp_enc.c", "bmp/bmp_cod.c", "ras/ras_dec.c", + "ras/ras_enc.c", "jp2/jp2_dec.c", "jp2/jp2_enc.c", "jp2/jp2_cod.c", + "jpc/jpc_cs.c", "jpc/jpc_enc.c", "jpc/jpc_dec.c", "jpc/jpc_t1cod.c", + "jpc/jpc_math.c", "jpc/jpc_util.c", "jpc/jpc_tsfb.c", "jpc/jpc_mct.c", + "jpc/jpc_t1enc.c", "jpc/jpc_t1dec.c", "jpc/jpc_bs.c", "jpc/jpc_t2cod.c", + "jpc/jpc_t2enc.c", "jpc/jpc_t2dec.c", "jpc/jpc_tagtree.c", + "jpc/jpc_mqenc.c", "jpc/jpc_mqdec.c", "jpc/jpc_mqcod.c", + "jpc/jpc_qmfb.c", "jpg/jpg_val.c", "jpg/jpg_dummy.c", "pgx/pgx_dec.c", + "pgx/pgx_enc.c"] + +libJ2kFile_src_path = "./../../../raster/Jp2" +input_j2k_sources = ["J2kFile.cpp", "Reader.cpp"] + sources = [] for item in input_raster_sources: sources.append(libRaster_src_path + '/' + item) @@ -92,12 +110,15 @@ for item in input_png_sources: sources.append(libPng_src_path + '/' + item) for item in input_tiff_sources: sources.append(libTiff_src_path + '/' + item) +for item in input_jasper_sources: + sources.append(libJasper_src_path + '/' + item) +for item in input_j2k_sources: + sources.append(libJ2kFile_src_path + '/' + item) sources.append("./wasm/src/base.cpp") compiler_flags.append("-I./../../../../OfficeUtils/src/zlib-1.2.11") -#compiler_flags.append("-I" + libCxImage_src_path) -#compiler_flags.append("-I" + libJpeg_src_path) -compiler_flags.append("-DBUILDING_WASM_MODULE -D_tcsnicmp=strncmp") +compiler_flags.append("-I" + libJasper_src_path + "/include") +compiler_flags.append("-DBUILDING_WASM_MODULE -D_tcsnicmp=strncmp -D_lseek=lseek") # arguments arguments = "" diff --git a/DesktopEditor/graphics/pro/js/qt/test/main.cpp b/DesktopEditor/graphics/pro/js/qt/test/main.cpp index 0c43f6ecc3..8c0ee2e9be 100644 --- a/DesktopEditor/graphics/pro/js/qt/test/main.cpp +++ b/DesktopEditor/graphics/pro/js/qt/test/main.cpp @@ -10,7 +10,7 @@ int main() BYTE* pData = NULL; DWORD nBytesCount; NSFile::CFileBinary oFile; - if (!oFile.ReadAllBytes(NSFile::GetProcessDirectory() + L"/test.png", &pData, nBytesCount)) + if (!oFile.ReadAllBytes(NSFile::GetProcessDirectory() + L"/test.jp2", &pData, nBytesCount)) return 1; oFile.CloseFile(); diff --git a/DesktopEditor/raster/BgraFrame.cpp b/DesktopEditor/raster/BgraFrame.cpp index b252c77689..4aa9ca85fd 100644 --- a/DesktopEditor/raster/BgraFrame.cpp +++ b/DesktopEditor/raster/BgraFrame.cpp @@ -418,21 +418,22 @@ void CBgraFrame::put_Palette(BYTE* pDataColors, const int& colors) bool CBgraFrame::OpenFile(const std::wstring& strFileName, unsigned int nFileType) { - m_nFileType = nFileType; - -#if CXIMAGE_SUPPORT_JP2 - if (CXIMAGE_FORMAT_JP2 == nFileType) - { - Jpeg2000::CJ2kFile oJ2; - return oJ2.Open(this, strFileName, std::wstring(L"")); - } -#endif + m_nFileType = nFileType; if (nFileType == 0) { CImageFileFormatChecker checker(strFileName); m_nFileType = checker.eFileType; } + +#if CXIMAGE_SUPPORT_JP2 + if (CXIMAGE_FORMAT_JP2 == m_nFileType) + { + Jpeg2000::CJ2kFile oJ2; + return oJ2.Open(this, strFileName, std::wstring(L"")); + } +#endif + NSFile::CFileBinary oFile; if (!oFile.OpenFile(strFileName)) return false; @@ -450,13 +451,20 @@ bool CBgraFrame::Decode(BYTE* pBuffer, int nSize, unsigned int nFileType) { m_nFileType = nFileType; - // добавить CXIMAGE_FORMAT_JP2 с буфером if (nFileType == 0) { CImageFileFormatChecker checker(pBuffer, nSize); m_nFileType = checker.eFileType; } +#if CXIMAGE_SUPPORT_JP2 + if (CXIMAGE_FORMAT_JP2 == m_nFileType) + { + Jpeg2000::CJ2kFile oJ2; + return oJ2.Open(this, pBuffer, nSize, std::wstring(L"")); + } +#endif + CxImage img; if (!img.Decode(pBuffer, nSize, m_nFileType)) diff --git a/DesktopEditor/raster/Jp2/J2kFile.cpp b/DesktopEditor/raster/Jp2/J2kFile.cpp index 35dc34c4e1..aa6c643633 100644 --- a/DesktopEditor/raster/Jp2/J2kFile.cpp +++ b/DesktopEditor/raster/Jp2/J2kFile.cpp @@ -77,6 +77,46 @@ namespace Jpeg2000 fseek(pFile, 0, SEEK_SET); return type; } + int check_j2000_type(BYTE* pBuffer, int nSize) + { + if (!pBuffer) + return 0; + + int type = 0; + if ((32 <= nSize) && (0x00 == pBuffer[0] && 0x00 == pBuffer[1] && 0x00 == pBuffer[2] && 0x0c == pBuffer[3] + && 0x6a == pBuffer[4] && 0x50 == pBuffer[5] && 0x20 == pBuffer[6] && 0x20 == pBuffer[7] + + && 0x0d == pBuffer[8] && 0x0a == pBuffer[9] && 0x87 == pBuffer[10] && 0x0a == pBuffer[11] + && 0x00 == pBuffer[12] && 0x00 == pBuffer[13] && 0x00 == pBuffer[14] /*&& (0x14 == pBuffer[15] || 0x18 == pBuffer[15] )*/ + + && 0x66 == pBuffer[16] && 0x74 == pBuffer[17] && 0x79 == pBuffer[18] && 0x70 == pBuffer[19] + && 0x6a == pBuffer[20] && 0x70 == pBuffer[21] && 0x32 == pBuffer[22] && 0x20 == pBuffer[23] + + && 0x00 == pBuffer[24] && 0x00 == pBuffer[25] && 0x00 == pBuffer[26] && 0x00 == pBuffer[27] + /*&& 0x6a == pBuffer[28] && 0x70 == pBuffer[29] && 0x32 == pBuffer[30] && 0x20 == pBuffer[31]*/)) + { + type = 1; + } + if ((4 <= nSize) && (0xff == pBuffer[0] && 0x4f == pBuffer[1] && 0xff == pBuffer[2] && 0x51 == pBuffer[3])) + { + type = 2; + } + if ((32 <= nSize) && (0x00 == pBuffer[0] && 0x00 == pBuffer[1] && 0x00 == pBuffer[2] && 0x0c == pBuffer[3] + && 0x6a == pBuffer[4] && 0x50 == pBuffer[5] && 0x20 == pBuffer[6] && 0x20 == pBuffer[7] + + && 0x0d == pBuffer[8] && 0x0a == pBuffer[9] && 0x87 == pBuffer[10] && 0x0a == pBuffer[11] + && 0x00 == pBuffer[12] && 0x00 == pBuffer[13] && 0x00 == pBuffer[14] && 0x18 == pBuffer[15] + + && 0x66 == pBuffer[16] && 0x74 == pBuffer[17] && 0x79 == pBuffer[18] && 0x70 == pBuffer[19] + && 0x6d == pBuffer[20] && 0x6a == pBuffer[21] && 0x70 == pBuffer[22] && 0x32 == pBuffer[23] + + && 0x00 == pBuffer[24] && 0x00 == pBuffer[25] && 0x00 == pBuffer[26] && 0x00 == pBuffer[27] + && 0x6d == pBuffer[28] && 0x6a == pBuffer[29] && 0x70 == pBuffer[30] && 0x32 == pBuffer[31])) + { + type = 3; + } + return type; + } // CJ2kFile bool CJ2kFile::Open(CBgraFrame* pFrame, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions) @@ -209,6 +249,128 @@ namespace Jpeg2000 Image_Destroy(pImage); return true; } + bool CJ2kFile::Open(CBgraFrame* pFrame, BYTE* pBuffer, int nSize, const std::wstring& wsXmlOptions) + { + Image *pImage = NULL; + + DecoderParams oParameters; + + // Установим стандартные значения параметров + ApplyDecoderOptions(&oParameters, wsXmlOptions); + + /////////////////////////////////////////////////////////////////////////////////// + + int type = check_j2000_type(pBuffer, nSize); + + bool bOpenResult = false; + if (!bOpenResult && type == 1) + bOpenResult = (NULL != (pImage = Jp2ToImage(pBuffer, nSize, &oParameters))); + + if (!bOpenResult && type == 2) + bOpenResult = (NULL != (pImage = J2kToImage(pBuffer, nSize, &oParameters))); + + if (!bOpenResult && type == 3) + bOpenResult = (NULL != (pImage = Mj2ToImage(pBuffer, nSize, &oParameters))); + + if (!bOpenResult && type == 4) + bOpenResult = (NULL != (pImage = JptToImage(pBuffer, nSize, &oParameters))); + + if (!bOpenResult) + { + Image_Destroy(pImage); + return false; + } + + int nWidth = pImage->pComponents[0].nWidth; + int nHeight = pImage->pComponents[0].nHeight; + int nBufferSize = 4 /*pImage->nCsiz*/ * nWidth * nHeight; + + if (nBufferSize < 1) + { + Image_Destroy(pImage); + return false; + } + + pFrame->put_Width(nWidth); + pFrame->put_Height(nHeight); + pFrame->put_Stride(4 * nWidth); + + BYTE* pData = new BYTE[nBufferSize]; + if (!pData) + { + Image_Destroy(pImage); + return false; + } + + pFrame->put_Data(pData); + + unsigned char* pBufferPtr = (unsigned char*)pData; + long nCreatedBufferSize = nBufferSize; + + // Пишем данные в pBufferPtr + if (pImage->nCsiz == 3 && pImage->pComponents[0].nXRsiz == pImage->pComponents[1].nXRsiz && pImage->pComponents[1].nXRsiz == pImage->pComponents[2].nXRsiz + && pImage->pComponents[0].nYRsiz == pImage->pComponents[1].nYRsiz && pImage->pComponents[1].nYRsiz == pImage->pComponents[2].nYRsiz + && pImage->pComponents[0].nPrecision == pImage->pComponents[1].nPrecision && pImage->pComponents[1].nPrecision == pImage->pComponents[2].nPrecision) + { + int nResW = CeilDivPow2(pImage->pComponents[0].nWidth, pImage->pComponents[0].nFactorDiv2); + int nResH = CeilDivPow2(pImage->pComponents[0].nHeight, pImage->pComponents[0].nFactorDiv2); + + + for (int nIndex = 0; nIndex < nResW * nResH; nIndex++) + { + unsigned char nR = pImage->pComponents[0].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + unsigned char nG = pImage->pComponents[1].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + unsigned char nB = pImage->pComponents[2].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + + pBufferPtr[0] = nB; + pBufferPtr[1] = nG; + pBufferPtr[2] = nR; + pBufferPtr[3] = 255; + pBufferPtr += 4; + + } + } + else if (pImage->nCsiz >= 4 && pImage->pComponents[0].nXRsiz == pImage->pComponents[1].nXRsiz && pImage->pComponents[1].nXRsiz == pImage->pComponents[2].nXRsiz && pImage->pComponents[2].nXRsiz == pImage->pComponents[3].nXRsiz + && pImage->pComponents[0].nYRsiz == pImage->pComponents[1].nYRsiz && pImage->pComponents[1].nYRsiz == pImage->pComponents[2].nYRsiz && pImage->pComponents[2].nYRsiz == pImage->pComponents[3].nYRsiz + && pImage->pComponents[0].nPrecision == pImage->pComponents[1].nPrecision && pImage->pComponents[1].nPrecision == pImage->pComponents[2].nPrecision && pImage->pComponents[2].nPrecision == pImage->pComponents[3].nPrecision) + { + int nResW = CeilDivPow2(pImage->pComponents[0].nWidth, pImage->pComponents[0].nFactorDiv2); + int nResH = CeilDivPow2(pImage->pComponents[0].nHeight, pImage->pComponents[0].nFactorDiv2); + + + for (int nIndex = 0; nIndex < nResW * nResH; nIndex++) + { + unsigned char nR = pImage->pComponents[0].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + unsigned char nG = pImage->pComponents[1].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + unsigned char nB = pImage->pComponents[2].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + unsigned char nA = pImage->pComponents[3].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + + pBufferPtr[0] = nB; + pBufferPtr[1] = nG; + pBufferPtr[2] = nR; + pBufferPtr[3] = nA; + pBufferPtr += 4; + } + } + else // Grayscale + { + int nResW = CeilDivPow2(pImage->pComponents[0].nWidth, pImage->pComponents[0].nFactorDiv2); + int nResH = CeilDivPow2(pImage->pComponents[0].nHeight, pImage->pComponents[0].nFactorDiv2); + + for (int nIndex = 0; nIndex < nResW * nResH; nIndex++) + { + unsigned char nG = pImage->pComponents[0].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; + pBufferPtr[0] = nG; + pBufferPtr[1] = nG; + pBufferPtr[2] = nG; + pBufferPtr[3] = 255; + pBufferPtr += 4; + } + } + + Image_Destroy(pImage); + return true; + } bool CJ2kFile::Open(BYTE** ppData, int& nComponentsCount, int& nWidth, int& nHeight, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions) { Image *pImage = NULL; diff --git a/DesktopEditor/raster/Jp2/J2kFile.h b/DesktopEditor/raster/Jp2/J2kFile.h index ab0b42aa2f..bab3a12fcd 100644 --- a/DesktopEditor/raster/Jp2/J2kFile.h +++ b/DesktopEditor/raster/Jp2/J2kFile.h @@ -9,6 +9,7 @@ namespace Jpeg2000 { public: bool Open(CBgraFrame* pFrame, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions); + bool Open(CBgraFrame* pFrame, BYTE* pBuffer, int nSize, const std::wstring& wsXmlOptions); bool Save(CBgraFrame* pFrame, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions); bool Open(BYTE** ppData, int& nComponentsCount, int& nWidth, int& nHeight, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions); diff --git a/DesktopEditor/raster/Jp2/J2kIncludes.h b/DesktopEditor/raster/Jp2/J2kIncludes.h index ee2899ecd0..0530b61804 100644 --- a/DesktopEditor/raster/Jp2/J2kIncludes.h +++ b/DesktopEditor/raster/Jp2/J2kIncludes.h @@ -188,6 +188,169 @@ namespace Jpeg2000 Free(pDInfo); return pImage; } + + Image* Jp2ToImage(BYTE* pBuffer, int nSize, DecoderParams* pDecoderParams) + { + DInfo *pDInfo = (DInfo*)Malloc(sizeof(DInfo)); + if (!pDInfo) + return NULL; + + pDInfo->bIsDecompressor = true; + pDInfo->pJp2 = (void*)Jp2_CreateDecompress((PCommon)pDInfo); + if (!pDInfo->pJp2) + { + Free(pDInfo); + return NULL; + } + + pDInfo->pJ2k = NULL; + pDInfo->eCodecFormat = codecJP2; + + Jp2_SetupDecoder((Jp2Stream*)pDInfo->pJp2, pDecoderParams); + if (JP2_ERROR_NO_ERROR != pDInfo->nErrorCode) + { + Jp2_DestroyDecompress((Jp2Stream*)pDInfo->pJp2); + Free(pDInfo); + return NULL; + } + + CReader *pStream = (CReader *)new CReaderStream(pBuffer, nSize); + if (!pStream) + { + Jp2_DestroyDecompress((Jp2Stream*)pDInfo->pJp2); + Free(pDInfo); + return NULL; + } + + Image *pImage = Jp2_Decode((Jp2Stream*)pDInfo->pJp2, pStream); // в случае ошибки pImage = NULL + delete (pStream); + Jp2_DestroyDecompress((Jp2Stream*)pDInfo->pJp2); + + Free(pDInfo); + return pImage; + } + Image* J2kToImage(BYTE* pBuffer, int nSize, DecoderParams* pDecoderParams) + { + DInfo *pDInfo = (DInfo*)Malloc(sizeof(DInfo)); + if (!pDInfo) + return NULL; + + pDInfo->bIsDecompressor = true; + pDInfo->pJ2k = (void*)J2k_CreateDecompress((PCommon)pDInfo); + if (!pDInfo->pJ2k) + { + Free(pDInfo); + return NULL; + } + + pDInfo->pJp2 = NULL; + pDInfo->eCodecFormat = codecJ2K; + + J2k_SetupDecoder((J2kCodestream*)pDInfo->pJ2k, pDecoderParams); + if (JP2_ERROR_NO_ERROR != pDInfo->nErrorCode) + { + J2k_DestroyDecompress((J2kCodestream*)pDInfo->pJ2k); + Free(pDInfo); + return NULL; + } + + CReader *pStream = (CReader *)new CReaderStream(pBuffer, nSize); + + if (!pStream) + { + J2k_DestroyDecompress((J2kCodestream*)pDInfo->pJ2k); + Free(pDInfo); + return NULL; + } + + Image *pImage = J2k_Decode((J2kCodestream*)pDInfo->pJ2k, pStream); // в случае ошибки pImage = NULL + delete (pStream); + J2k_DestroyDecompress((J2kCodestream*)pDInfo->pJ2k); + + Free(pDInfo); + + return pImage; + } + Image* JptToImage(BYTE* pBuffer, int nSize, DecoderParams* pDecoderParams) + { + DInfo *pDInfo = (DInfo*)Malloc(sizeof(DInfo)); + if (!pDInfo) + return NULL; + + pDInfo->bIsDecompressor = true; + pDInfo->pJ2k = (void*)J2k_CreateDecompress((PCommon)pDInfo); + if (!pDInfo->pJ2k) + { + Free(pDInfo); + return NULL; + } + + pDInfo->pJp2 = NULL; + pDInfo->eCodecFormat = codecJPT; + + J2k_SetupDecoder((J2kCodestream*)pDInfo->pJ2k, pDecoderParams); + if (JP2_ERROR_NO_ERROR != pDInfo->nErrorCode) + { + J2k_DestroyDecompress((J2kCodestream*)pDInfo->pJ2k); + Free(pDInfo); + return NULL; + } + + CReader *pStream = (CReader *)new CReaderStream(pBuffer, nSize); + if (!pStream) + { + J2k_DestroyDecompress((J2kCodestream*)pDInfo->pJ2k); + Free(pDInfo); + return NULL; + } + + Image *pImage = J2k_DecodeJptStream((J2kCodestream*)pDInfo->pJ2k, pStream); // в случае ошибки pImage = NULL + delete (pStream); + J2k_DestroyDecompress((J2kCodestream*)pDInfo->pJ2k); + + Free(pDInfo); + return NULL; + } + Image* Mj2ToImage(BYTE* pBuffer, int nSize, DecoderParams* pDecoderParams) + { + DInfo *pDInfo = (DInfo*)Malloc(sizeof(DInfo)); + if (!pDInfo) + return NULL; + + pDInfo->bIsDecompressor = true; + pDInfo->pMj2 = (void*)Mj2_CreateDecompress((PCommon)pDInfo); + if (!pDInfo->pMj2) + { + Free(pDInfo); + return NULL; + } + + pDInfo->pJ2k = ((Mj2_Movie*)pDInfo->pMj2)->pJ2k; + pDInfo->eCodecFormat = codecMj2; + + Mj2_SetupDecoder((Mj2_Movie*)pDInfo->pMj2, pDecoderParams); + if (JP2_ERROR_NO_ERROR != pDInfo->nErrorCode) + { + Mj2_DestroyDecompress((Mj2_Movie*)pDInfo->pMj2); + Free(pDInfo); + return NULL; + } + + CReader *pStream = (CReader *)new CReaderStream(pBuffer, nSize); + if (!pStream) + { + Mj2_DestroyDecompress((Mj2_Movie*)pDInfo->pMj2); + Free(pDInfo); + return NULL; + } + + Image *pImage = Mj2_Decode((Mj2_Movie*)pDInfo->pMj2, pStream); // в случае ошибки pImage = NULL + delete (pStream); + Mj2_DestroyDecompress((Mj2_Movie*)pDInfo->pMj2); + + Free(pDInfo); + return pImage; + } //------------------------------------------------------------------------------------------------------------------------------- // Image -> Jpeg2000 //------------------------------------------------------------------------------------------------------------------------------- @@ -313,4 +476,4 @@ namespace Jpeg2000 return true; } -} \ No newline at end of file +} diff --git a/DesktopEditor/raster/Jp2/Jp2.h b/DesktopEditor/raster/Jp2/Jp2.h index dcca584d5c..e4d36b5a6c 100644 --- a/DesktopEditor/raster/Jp2/Jp2.h +++ b/DesktopEditor/raster/Jp2/Jp2.h @@ -51,7 +51,7 @@ namespace Jpeg2000 if (sIndexFile) { - for (unsigned int nIndex = 0; nIndex < strlen(sIndexFile); nIndex) + for (unsigned int nIndex = 0; nIndex < strlen(sIndexFile); nIndex++) { pStream->Write(sIndexFile[nIndex], 1); } @@ -759,4 +759,4 @@ namespace Jpeg2000 return true; } -} \ No newline at end of file +}