long* histogram(char* fn_input) { pImage image; int i, j, m, c, d, id; long* histo; time_t t0, t1; /* time_t is defined on <time.h> and <sys/types.h> as long */ clock_t c0, c1; /* clock_t is defined on <time.h> and <sys/types.h> as int */ long count; /* initalization & reading image file */ histo = malloc(256*sizeof(long)); image = Image_Read(fn_input); long temp[8][256]; for(c=0; c<256; c++) for(d=0; d<8; d++){ temp[d][c]=0;} t0 = time(NULL); c0 = clock(); /* obtain histogram from image, repeated 10 times */ for (m=0; m<10; m++) { #pragma omp parallel for default(shared) private(i,j,id) num_threads (8) for (i=0; i<image->row; i++) { id = omp_get_thread_num(); for (j=0; j<image->col; j++) { // assert(image->content[i][j] >=0 && image->content[i][j] < 256); temp[id][image->content[i][j]]++; } } } /* ------- Termination */ t1 = time(NULL); c1 = clock(); printf ("\t Wall clock time: %ld\n", (long) (t1 - t0)); for(c=0; c<256; c++){ for(d=0; d<8; d++){ histo[c] = histo[c]+temp[d][c];}} Image_Destroy(&image); printf("--- Histogram Content ---\n"); for (i=0; i<256; i++) printf("histo[%d] = %d\n", i, histo[i]); return histo; }
// CJ2kFile bool CJ2kFile::Open(CBgraFrame* pFrame, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions) { Image *pImage = NULL; DecoderParams oParameters; // Установим стандартные значения параметров ApplyDecoderOptions(&oParameters, wsXmlOptions); /////////////////////////////////////////////////////////////////////////////////// NSFile::CFileBinary oFile; if (!oFile.OpenFile(wsSrcPath)) return false; DWORD nFileSize = oFile.GetFileSize(); int type = check_j2000_type(oFile.GetFileNative()); oFile.CloseFile(); bool bOpenResult = false; if (!bOpenResult && type == 1) bOpenResult = (NULL != (pImage = Jp2ToImage(wsSrcPath, &oParameters))); if (!bOpenResult && type == 2) bOpenResult = (NULL != (pImage = J2kToImage(wsSrcPath, &oParameters))); if (!bOpenResult && type == 3) bOpenResult = (NULL != (pImage = Mj2ToImage(wsSrcPath, &oParameters))); if (!bOpenResult && type == 4) bOpenResult = (NULL != (pImage = JptToImage(wsSrcPath, &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::Save(CBgraFrame* pFrame, const std::wstring& wsDstPath, const std::wstring& wsXmlOptions) { // TODO: Запись не реализована, надо доделать. return false; if (!pFrame) return false; LONG lWidth = pFrame->get_Width(); LONG lHeight = pFrame->get_Height(); BYTE* pSourceBuffer = pFrame->get_Data(); LONG lBufferSize = 4 * lWidth * lHeight; // Далее обрабатываем Xml с параметрами компрессии EncoderParams oParameters; int nFormat = ApplyEncoderOptions(&oParameters, wsXmlOptions); // TODO: Добавить возможность записи альфа-канала ImageComponentParams aComponentParams[3]; // Пока пусть будет максимально три компоненты (RGB) Image *pImage = NULL; int nComponentsCount = oParameters.nComponentsCount; memset(&aComponentParams[0], 0, sizeof(ImageComponentParams)); for (int nIndex = 0; nIndex < nComponentsCount; nIndex++) { aComponentParams[nIndex].nPrecision = 8; aComponentParams[nIndex].nBPP = 8; aComponentParams[nIndex].nSigned = 0; aComponentParams[nIndex].nXRsiz = oParameters.nSubSamplingDx; aComponentParams[nIndex].nYRsiz = oParameters.nSubSamplingDy; aComponentParams[nIndex].nWidth = (int)lWidth; aComponentParams[nIndex].nHeight = (int)lHeight; } // Создаем структуру Image pImage = Image_Create(nComponentsCount, &aComponentParams[0], csRGB); if (!pImage) return false; pImage->nXOsiz = oParameters.nImageOffsetX0; pImage->nYOsiz = oParameters.nImageOffsetY0; pImage->nXsiz = (!pImage->nXOsiz) ? (lWidth - 1) * oParameters.nSubSamplingDx + 1 : pImage->nXOsiz + (lWidth - 1) * oParameters.nSubSamplingDy + 1; pImage->nYsiz = (!pImage->nYOsiz) ? (lHeight - 1) * oParameters.nSubSamplingDy + 1 : pImage->nYOsiz + (lHeight - 1) * oParameters.nSubSamplingDy + 1; if (3 == nComponentsCount) { int nIndex = 0; for (int nY = 0; nY < (int)lHeight; nY++) { for (int nX = 0; nX < (int)lWidth; nX++, pSourceBuffer += 4) { pImage->pComponents[0].pData[nIndex] = pSourceBuffer[2]; pImage->pComponents[1].pData[nIndex] = pSourceBuffer[1]; pImage->pComponents[2].pData[nIndex] = pSourceBuffer[0]; nIndex++; } } } else if (1 == nComponentsCount) { int nIndex = 0; for (int nY = 0; nY < (int)lHeight; nY++) { for (int nX = 0; nX < (int)lWidth; nX++, pSourceBuffer += 4) { pImage->pComponents[0].pData[nIndex] = pSourceBuffer[0]; nIndex++; } } } else { Image_Destroy(pImage); return false; } bool bRes = false; switch (nFormat) { case 0: bRes = ImageToJ2k(pImage, wsDstPath, &oParameters); break; case 1: bRes = ImageToJ2p(pImage, wsDstPath, &oParameters); break; case -1: default: bRes = false; } Image_Destroy(pImage); return bRes; }
bool CJ2kFile::Open(BYTE** ppData, int& nComponentsCount, int& nWidth, int& nHeight, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions) { Image *pImage = NULL; DecoderParams oParameters; // Установим стандартные значения параметров ApplyDecoderOptions(&oParameters, wsXmlOptions); /////////////////////////////////////////////////////////////////////////////////// NSFile::CFileBinary oFile; if (!oFile.OpenFile(wsSrcPath)) return false; DWORD nFileSize = oFile.GetFileSize(); int type = check_j2000_type(oFile.GetFileNative()); oFile.CloseFile(); bool bOpenResult = false; if (!bOpenResult && type == 1) bOpenResult = (NULL != (pImage = Jp2ToImage(wsSrcPath, &oParameters))); if (!bOpenResult && type == 2) bOpenResult = (NULL != (pImage = J2kToImage(wsSrcPath, &oParameters))); if (!bOpenResult && type == 3) bOpenResult = (NULL != (pImage = Mj2ToImage(wsSrcPath, &oParameters))); if (!bOpenResult && type == 4) bOpenResult = (NULL != (pImage = JptToImage(wsSrcPath, &oParameters))); if (!bOpenResult) { Image_Destroy(pImage); return false; } nWidth = pImage->pComponents[0].nWidth; nHeight = pImage->pComponents[0].nHeight; int nBufferSize = pImage->nCsiz * nWidth * nHeight; if (nBufferSize < 1 || pImage->nCsiz <= 0) { Image_Destroy(pImage); return false; } *ppData = new BYTE[nBufferSize]; if (!(*ppData)) { Image_Destroy(pImage); return false; } unsigned char* pBufferPtr = (unsigned char*)(*ppData); long nCreatedBufferSize = nBufferSize; nComponentsCount = pImage->nCsiz; // Пишем данные в pBufferPtr for (int nComponent = 1; nComponent < nComponentsCount; nComponent++) { if (pImage->pComponents[0].nXRsiz != pImage->pComponents[nComponent].nXRsiz || pImage->pComponents[0].nYRsiz != pImage->pComponents[nComponent].nYRsiz || pImage->pComponents[0].nPrecision != pImage->pComponents[nComponent].nPrecision) { delete[](*ppData); Image_Destroy(pImage); return false; } } 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++) { for (int nComponent = 0; nComponent < nComponentsCount; nComponent++) { pBufferPtr[nComponent] = pImage->pComponents[nComponent].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)]; } pBufferPtr += nComponentsCount; } Image_Destroy(pImage); return true; }