int jpeg_decompress_8u_rgb_IPP (const uint8_t * src, int src_size, uint8_t * dest, int width, int height, int stride) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; struct jpeg_source_mgr jsrc; cinfo.err = jpeg_std_error (&jerr); jpeg_create_decompress (&cinfo); jsrc.next_input_byte = src; jsrc.bytes_in_buffer = src_size; jsrc.init_source = init_source; jsrc.fill_input_buffer = fill_input_buffer; jsrc.skip_input_data = skip_input_data; jsrc.resync_to_restart = jpeg_resync_to_restart; jsrc.term_source = term_source; cinfo.src = &jsrc; jpeg_read_header (&cinfo, TRUE); cinfo.out_color_space = JCS_RGB; jpeg_calc_output_dimensions (&cinfo); if (cinfo.output_height < height || cinfo.output_width < width) { fprintf (stderr, "Error: Buffer is %dx%d but JPEG image is %dx%d\n", width, height, cinfo.output_width, cinfo.output_height); jpeg_destroy_decompress (&cinfo); return -1; } jvirt_barray_ptr * dct_planes = jpeg_read_coefficients (&cinfo); uint8_t * tmp_plane = NULL; uint8_t * full_plane[cinfo.num_components]; int full_stride; int tmp_stride; int max_h_samp=1, max_v_samp=1; int c, i, j; jpeg_component_info * c0 = cinfo.cur_comp_info[0]; for (c = 0; c < cinfo.num_components; c++) { full_plane[c] = ippiMalloc_8u_C1 (c0->width_in_blocks*8, c0->height_in_blocks*8, &full_stride); jpeg_component_info * comp = cinfo.cur_comp_info[c]; if (comp->h_samp_factor > max_h_samp) max_h_samp = comp->h_samp_factor; if (comp->v_samp_factor > max_v_samp) max_v_samp = comp->v_samp_factor; } for (c = 0; c < cinfo.num_components; c++) { jpeg_component_info * comp = cinfo.cur_comp_info[c]; uint8_t * plane; int pstride, offset; int h_samp = max_h_samp / comp->h_samp_factor; int v_samp = max_v_samp / comp->v_samp_factor; if (h_samp == 2 && v_samp == 2) { if (!tmp_plane) tmp_plane = ippiMalloc_8u_C1 (comp->width_in_blocks*8 + 16, comp->height_in_blocks*8 + 2, &tmp_stride); plane = tmp_plane; pstride = tmp_stride; offset = tmp_stride + 8; } else if (h_samp == 1 && v_samp == 1) { plane = full_plane[c]; pstride = full_stride; offset = 0; } for (i = 0; i < comp->height_in_blocks; i++) { JBLOCKARRAY bar = cinfo.mem->access_virt_barray ( (j_common_ptr) &cinfo, dct_planes[c], i, 1, FALSE); JBLOCKROW row = bar[0]; uint8_t * drow = plane + 8*i*pstride + offset; for (j = 0; j < comp->width_in_blocks; j++) { JBLOCK * blk = row + j; ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R (*blk, drow + j*8, pstride, cinfo.quant_tbl_ptrs[comp->quant_tbl_no]->quantval); } } if (h_samp == 2 && v_samp == 2) { IppiSize srcroi = { 8*comp->width_in_blocks, 8*comp->height_in_blocks }; IppiSize dstroi = { 8*comp->width_in_blocks + 2, 8*comp->height_in_blocks + 2 }; ippiCopyReplicateBorder_8u_C1IR (tmp_plane + tmp_stride + 8, tmp_stride, srcroi, dstroi, 1, 1); dstroi.width = width; dstroi.height = height; ippiSampleUpH2V2_JPEG_8u_C1R (tmp_plane + tmp_stride + 8, tmp_stride, srcroi, full_plane[c], full_stride, dstroi); } } IppiSize dstroi = { width, height }; ippiYCbCrToRGB_JPEG_8u_P3C3R ((const uint8_t **)full_plane, full_stride, dest, stride, dstroi); for (c = 0; c < cinfo.num_components; c++) ippiFree (full_plane[c]); if (tmp_plane) ippiFree (tmp_plane); jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); return 0; }
int jpeg_compress_8u_rgb_IPP (const uint8_t * src, int width, int height, int stride, uint8_t * dest, int * destsize, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; struct jpeg_destination_mgr jdest; int out_size = *destsize; cinfo.err = jpeg_std_error (&jerr); jpeg_create_compress (&cinfo); jdest.next_output_byte = dest; jdest.free_in_buffer = out_size; jdest.init_destination = init_destination; jdest.empty_output_buffer = empty_output_buffer; jdest.term_destination = term_destination; cinfo.dest = &jdest; cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, quality, TRUE); jvirt_barray_ptr barptr[3]; for (c = 0; c < cinfo.num_components; c++) { jpeg_component_info * comp = cinfo.cur_comp_info[c]; barptr[c] = cinfo.mem->request_virt_barray (&cinfo, JPOOL_IMAGE, FALSE, cinfo->width_in_blocks, cinfo->height_in_blocks, cinfo->height_in_blocks); } jpeg_write_coefficients (&cinfo, barptr); for (c = 0; c < cinfo.num_components; c++) { jpeg_component_info * comp = cinfo.cur_comp_info[c]; uint8_t * plane; int pstride; int h_samp = max_h_samp / comp->h_samp_factor; int v_samp = max_v_samp / comp->v_samp_factor; if (h_samp == 2 && v_samp == 2) { if (!tmp_plane) tmp_plane = ippiMalloc_8u_C1 (comp->width_in_blocks*8, comp->height_in_blocks*8, &tmp_stride); plane = tmp_plane; pstride = tmp_stride; } else if (h_samp == 1 && v_samp == 1) { plane = full_plane[c]; pstride = full_stride; } for (i = 0; i < comp->height_in_blocks; i++) { JBLOCKARRAY bar = cinfo.mem->access_virt_barray ( (j_common_ptr) &cinfo, dct_planes[c], i, 1, TRUE); JBLOCKROW row = bar[0]; uint8_t * srow = plane + 8*i*pstride; for (j = 0; j < comp->width_in_blocks; j++) { JBLOCK * blk = row + j; ippiDCTQuantFwd8x8LS_JPEG_8u16s_C1R (srow + j*8, pstride, *blk, cinfo.quant_tbl_ptrs[comp->quant_tbl_no]->quantval); } } if (h_samp == 2 && v_samp == 2) { IppiSize srcroi = { 8*comp->width_in_blocks, 8*comp->height_in_blocks }; IppiSize dstroi = { 8*comp->width_in_blocks + 2, 8*comp->height_in_blocks + 2 }; ippiCopyReplicateBorder_8u_C1IR (tmp_plane + tmp_stride + 8, tmp_stride, srcroi, dstroi, 1, 1); dstroi.width = width; dstroi.height = height; ippiSampleUpH2V2_JPEG_8u_C1R (tmp_plane + tmp_stride + 8, tmp_stride, srcroi, full_plane[c], full_stride, dstroi); } } #if 0 jpeg_start_compress (&cinfo, TRUE); while (cinfo.next_scanline < height) { JSAMPROW row = (JSAMPROW)(src + cinfo.next_scanline * stride); jpeg_write_scanlines (&cinfo, &row, 1); } #endif jpeg_finish_compress (&cinfo); *destsize = out_size - jdest.free_in_buffer; jpeg_destroy_compress (&cinfo); return 0; }
//실행부분 void CIPPDlg::OnBnClickedButton1() { UpdateData(TRUE); CWaitCursor wait; LARGE_INTEGER frequency, tStart, tEnd; QueryPerformanceFrequency(&frequency); IppiSize maskSize = { 3, 3 }; IppiPoint anchor = { 1, 1 }; IppiSize sizeSrc = { m_nWidth, m_nHeight }; IppiSize sizeDst = { m_nWidth, m_nHeight }; IppiSize szFiltter = { m_nWidth - 2, m_nHeight - 2 };// Filter ROI Size 3x3=2, 5x5=4 // Step Size int nStepSrc = (8 * sizeSrc.width + 31) / 32 * 4;// Step = ((BitSize * Width + 31) / 32) * 4 int nStepDst = (8 * sizeDst.width + 31) / 32 * 4; int nStepTmp = (8 * szFiltter.width + 31) / 32 * 4; // 메모리 할당 Ipp8u* pipDataSrc = ippiMalloc_8u_C1(sizeSrc.width, sizeSrc.height, &nStepSrc); Ipp8u* pipDataDst = ippiMalloc_8u_C1(sizeDst.width, sizeDst.height, &nStepDst); //Ipp8u* pipDataTmp = (Ipp8u*)ippMalloc( nStepTmp * szFiltter.height); IppStatus status = ippStsNoErr; // 메모리 초기화 status = ippiImageJaehne_8u_C1R(pipDataSrc, nStepSrc, sizeSrc); status = ippiImageJaehne_8u_C1R(pipDataDst, nStepDst, sizeDst); //status = ippiImageJaehne_8u_C1R(pipDataTmp, nStepTmp, szFiltter); GetDlgItem(IDC_STATUS)->SetWindowText(ippGetStatusString(status)); // 원본 버퍼저장 CStdioFile rfile1; rfile1.Open("c:\\ipp_8u_1.raw", CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); rfile1.Write(pipDataSrc, sizeof(Ipp8u)*nStepSrc*m_nHeight); rfile1.Close(); // ROI 시작부분 계산 Ipp8u* pipSrcROI = (Ipp8u*)(((Ipp8u*)pipDataSrc) + anchor.y * nStepSrc + anchor.x * sizeof(Ipp8u)); Ipp8u* pipDstROI = (Ipp8u*)(((Ipp8u*)pipDataDst) + anchor.y * nStepDst + anchor.x * sizeof(Ipp8u)); QueryPerformanceCounter(&tStart); switch (m_idxFilter) { case 0://Sharpen status = ippiFilterSharpen_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter); break; case 1://Lowpass status = ippiFilterLowpass_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, ippMskSize3x3); break; case 2://Hipass status = ippiFilterHipass_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, ippMskSize3x3); break; case 3://Gauss status = ippiFilterGauss_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, ippMskSize3x3); break; case 4://Median status = ippiFilterMedian_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, maskSize, anchor); break; case 5://Min status = ippiFilterMin_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, maskSize, anchor); break; case 6://Max status = ippiFilterMax_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, maskSize, anchor); break; case 7://Laplace status = ippiFilterLaplace_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, ippMskSize3x3); break; case 8://Wiener { int size = 0; status = ippiFilterWienerGetBufferSize(szFiltter, maskSize, 1, &size); Ipp8u* pBuffer = new Ipp8u[size + 2]; Ipp32f noise = 0; status = ippiFilterWiener_8u_C1R(pipSrcROI, nStepSrc, pipDstROI, nStepDst, szFiltter, maskSize, anchor, &noise, (Ipp8u*)pBuffer); delete pBuffer; } break; } QueryPerformanceCounter(&tEnd); // 필터링된 버퍼저장 CStdioFile rfile2; rfile2.Open("c:\\ipp_8u_2.raw", CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); rfile2.Write(pipDataDst, sizeof(Ipp8u)*nStepDst * sizeDst.height); rfile2.Close(); Ipp64f Mean = 0; Ipp64f StdDev = 0; status = ippiMean_StdDev_8u_C1R(pipDataDst, nStepDst, sizeDst, &Mean, &StdDev); // 메모리 해제 ippiFree(pipDataSrc); ippiFree(pipDataDst); //ippiFree(pipDataTmp); GetDlgItem(IDC_STATUS)->SetWindowText(ippGetStatusString(status)); // 수행시간 계산 CString strTime; strTime.Format("%3.5f msec\r\nMean = %3.2f , StdDev = %3.2f", (double)((tEnd.QuadPart - tStart.QuadPart) / (double)frequency.QuadPart)*(double)1000., Mean, StdDev); GetDlgItem(IDC_TIME)->SetWindowText(strTime); }