/*******************************************************************************
* Copyright 2012 Intel Corporation.
*
*
* This software and the related documents are Intel copyrighted materials, and your use of them is governed by
* the express license under which they were provided to you ('License'). Unless the License provides otherwise,
* you may not use, modify, copy, publish, distribute, disclose or transmit this software or the related
* documents without Intel's prior written permission.
* This software and the related documents are provided as is, with no express or implied warranties, other than
* those that are expressly stated in the License.
*******************************************************************************/
#include <math.h>
#include <memory>
#include "base.h"
#include "base_image.h"
#include "base_ipp.h"
#include "base_renderer.h"
#include "ippcore.h"
#include "ipps.h"
#include "ippi.h"
//#define USE_TBB
#ifdef USE_TBB
//#define __TBB_NO_IMPLICIT_LINKAGE 0
#define TBB_PREVIEW_MEMORY_POOL 1
#include "tbb/task_arena.h"
#include "tbb/parallel_for.h"
#include "tbb/blocked_range2d.h"
#include "tbb/memory_pool.h"
#define TBB_PREVIEW_GLOBAL_CONTROL 1
#include "tbb/global_control.h"
using namespace tbb;
#endif
#define CMD_INTER_NN 0
#define CMD_INTER_LIN 1
#define CMD_INTER_CUB 2
#define CMD_INTER_LAN 3
static void printVersion()
{
const IppLibraryVersion *pVersion;
printf("\nIntel(R) IPP:\n");
PRINT_LIB_VERSION( , pVersion)
PRINT_LIB_VERSION(s, pVersion)
PRINT_LIB_VERSION(i, pVersion)
}
static void printHelp(const cmd::OptDef pOptions[], char* argv[])
{
printf("\nUsage: %s [-i] InputFile [[-o] OutputFile] [Options]\n", GetProgName(argv));
printf("Options:\n");
cmd::OptUsage(pOptions);
}
class Resize
{
public:
Resize()
{
m_iThreads = 0;
m_interpolation = ippLinear;
m_pSpec = 0;
m_pInitBuffer = 0;
m_antiAliasing = 0;
m_fBVal = 1;
m_fCVal = 0;
m_iLobes = 3;
}
virtual ~Resize()
{
Close();
}
void Close()
{
if(m_pSpec)
{
ippsFree(m_pSpec);
m_pSpec = 0;
}
if(m_pInitBuffer)
{
ippsFree(m_pInitBuffer);
m_pInitBuffer = 0;
}
}
virtual Status Init(Image *pSrcImage, Image *pDstImage)
{
IppStatus ippSts;
IppiBorderSize borderSize;
int iSpecSize = 0;
int iInitSize = 0;
if(!pSrcImage || !pSrcImage->ptr() || !pDstImage)
return STS_ERR_NULL_PTR;
if(pSrcImage->m_samples != 1 && pSrcImage->m_samples != 3 && pSrcImage->m_samples != 4)
return STS_ERR_INVALID_PARAMS;
Close();
IppiSize srcSize = {static_cast<int>(pSrcImage->m_size.width), static_cast<int>(pSrcImage->m_size.height)};
IppiSize dstSize = {static_cast<int>(pDstImage->m_size.width), static_cast<int>(pDstImage->m_size.height)};
// Get sizes for internal and initialization buffers
ippSts = ippiResizeGetSize_8u(srcSize, dstSize, m_interpolation, m_antiAliasing, &iSpecSize, &iInitSize);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeGetSize_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
// allocate internal buffer
m_pSpec = (IppiResizeSpec_32f*)ippsMalloc_8u(iSpecSize);
if(!m_pSpec)
{
PRINT_MESSAGE("Cannot allocate memory for resize spec");
return STS_ERR_ALLOC;
}
// allocate initialization buffer
if(iInitSize)
{
m_pInitBuffer = ippsMalloc_8u(iInitSize);
if(!m_pInitBuffer)
{
PRINT_MESSAGE("Cannot allocate memory for resize init buffer");
return STS_ERR_ALLOC;
}
}
// init ipp resizer
if(m_interpolation == ippNearest)
{
ippSts = ippiResizeNearestInit_8u(srcSize, dstSize, m_pSpec);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeNearestInit_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
}
else if(m_interpolation == ippLinear)
{
if (m_antiAliasing)
{
ippSts = ippiResizeAntialiasingLinearInit(srcSize, dstSize, m_pSpec, m_pInitBuffer);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeAntialiasingLinearInit()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
}
else {
ippSts = ippiResizeLinearInit_8u(srcSize, dstSize, m_pSpec);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeLinearInit_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
}
}
else if(m_interpolation == ippCubic)
{
if (m_antiAliasing)
{
ippSts = ippiResizeAntialiasingCubicInit(srcSize, dstSize, m_fBVal, m_fCVal, m_pSpec, m_pInitBuffer);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeAntialiasingCubicInit()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
}
else
{
ippSts = ippiResizeCubicInit_8u(srcSize, dstSize, m_fBVal, m_fCVal, m_pSpec, m_pInitBuffer);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeCubicInit_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
}
}
else if(m_interpolation == ippLanczos)
{
if (m_antiAliasing) {
ippSts = ippiResizeAntialiasingLanczosInit(srcSize, dstSize, m_iLobes, m_pSpec, m_pInitBuffer);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeAntialiasingLanczosInit()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
}
else {
ippSts = ippiResizeLanczosInit_8u(srcSize, dstSize, m_iLobes, m_pSpec, m_pInitBuffer);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeLanczosInit_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
}
}
ippSts = ippiResizeGetBorderSize_8u(m_pSpec, &borderSize);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeGetBorderSize_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
m_templ = *pSrcImage;
return STS_OK;
}
Status ResizeBlock(Image *pSrcImage, Image *pDstImage, Rect roi, IppiBorderType border, unsigned char *pExtBuffer = 0)
{
Status status;
IppStatus ippSts;
IppiPoint dstRoiOffset = {(int)roi.x, (int)roi.y};
IppiSize dstRoiSize = {(int)roi.width, (int)roi.height};
IppiPoint srcRoiOffset;
IppiSize srcRoiSize;
unsigned char *pSrcPtr = 0;
unsigned char *pDstPtr = 0;
unsigned char *pBuffer = 0;
int iBufferSize = 0;
if(!pSrcImage || !pDstImage)
return STS_ERR_NULL_PTR;
if(!m_pSpec)
return STS_ERR_NOT_INITIALIZED;
// Zero size mean full size
if(!dstRoiSize.width)
dstRoiSize.width = (int)pDstImage->m_size.width;
if(!dstRoiSize.height)
dstRoiSize.height = (int)pDstImage->m_size.height;
if(m_templ != *pSrcImage)
{
status = Init(pSrcImage, pDstImage);
CHECK_STATUS_PRINT_RS(status, "Resize::Init()", GetBaseStatusString(status));
}
// get src ROI from dst ROI
ippSts = ippiResizeGetSrcRoi_8u(m_pSpec, dstRoiOffset, dstRoiSize, &srcRoiOffset, &srcRoiSize);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeGetSrcRoi_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
// adjust input and output buffers to current ROI
pSrcPtr = (unsigned char*)pSrcImage->ptr(srcRoiOffset.y, srcRoiOffset.x);
pDstPtr = (unsigned char*)pDstImage->ptr(dstRoiOffset.y, dstRoiOffset.x);
if(!pExtBuffer)
{
ippSts = ippiResizeGetBufferSize_8u(m_pSpec, dstRoiSize, pSrcImage->m_samples, &iBufferSize);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeGetBufferSize_8u()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
pBuffer = ippsMalloc_8u(iBufferSize);
if(!pBuffer)
{
PRINT_MESSAGE("Cannot allocate memory for resize buffer");
return STS_ERR_ALLOC;
}
}
else
pBuffer = pExtBuffer;
// perform resize
if(m_interpolation == ippNearest)
{
if(pSrcImage->m_samples == 1)
ippSts = ippiResizeNearest_8u_C1R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, m_pSpec, pBuffer);
else if(pSrcImage->m_samples == 3)
ippSts = ippiResizeNearest_8u_C3R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, m_pSpec, pBuffer);
else if(pSrcImage->m_samples == 4)
ippSts = ippiResizeNearest_8u_C4R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, m_pSpec, pBuffer);
}
else if(m_antiAliasing)
{
if(pSrcImage->m_samples == 1)
ippSts = ippiResizeAntialiasing_8u_C1R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if(pSrcImage->m_samples == 3)
ippSts = ippiResizeAntialiasing_8u_C3R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if(pSrcImage->m_samples == 4)
ippSts = ippiResizeAntialiasing_8u_C4R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
}
else if (m_interpolation == ippLinear)
{
if (pSrcImage->m_samples == 1)
ippSts = ippiResizeLinear_8u_C1R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if (pSrcImage->m_samples == 3)
ippSts = ippiResizeLinear_8u_C3R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if (pSrcImage->m_samples == 4)
ippSts = ippiResizeLinear_8u_C4R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
}
else if (m_interpolation == ippCubic)
{
if (pSrcImage->m_samples == 1)
ippSts = ippiResizeCubic_8u_C1R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if (pSrcImage->m_samples == 3)
ippSts = ippiResizeCubic_8u_C3R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if (pSrcImage->m_samples == 4)
ippSts = ippiResizeCubic_8u_C4R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
}
else if (m_interpolation == ippLanczos)
{
if (pSrcImage->m_samples == 1)
ippSts = ippiResizeLanczos_8u_C1R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if (pSrcImage->m_samples == 3)
ippSts = ippiResizeLanczos_8u_C3R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
else if (pSrcImage->m_samples == 4)
ippSts = ippiResizeLanczos_8u_C4R(pSrcPtr, (int)pSrcImage->m_step, pDstPtr, (int)pDstImage->m_step, dstRoiOffset, dstRoiSize, border, 0, m_pSpec, pBuffer);
}
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeX_8u_CXR()", ippGetStatusString(ippSts), return STS_ERR_FAILED);
if(!pExtBuffer)
ippsFree(pBuffer);
return STS_OK;
}
virtual Status ResizeImage(Image *pSrcImage, Image *pDstImage)
{
if(!pSrcImage || !pDstImage)
return STS_ERR_NULL_PTR;
Rect roi(pDstImage->m_size.width, pDstImage->m_size.height);
return ResizeBlock(pSrcImage, pDstImage, roi, ippBorderRepl);
}
public:
unsigned int m_iThreads;
IppiInterpolationType m_interpolation;
int m_antiAliasing;
float m_fBVal;
float m_fCVal;
unsigned int m_iLobes;
protected:
Image m_templ;
IppiResizeSpec_32f *m_pSpec;
unsigned char *m_pInitBuffer;
};
#ifdef USE_TBB
class ResizeTBB : public Resize
{
public:
ResizeTBB()
{
m_iGrainX = 0;
m_iGrainY = 0;
}
Status Init(Image *pSrcImage, Image *pDstImage)
{
Status status;
status = Resize::Init(pSrcImage, pDstImage);
CHECK_STATUS_PRINT_RS(status, "Resize::Init()", GetBaseStatusString(status));
if(m_iThreads == 0) // automatic threads number
{
#if TBB_INTERFACE_VERSION >= 9100
m_iThreads = this_task_arena::max_concurrency();
#else
m_iThreads = task_arena::max_concurrency();
#endif
}
if(!m_iGrainX)
m_iGrainX = (unsigned int)(pDstImage->m_size.width + m_iThreads - 1)/m_iThreads;
if(!m_iGrainY)
m_iGrainY = (unsigned int)(pDstImage->m_size.height + m_iThreads - 1)/m_iThreads;
m_task.m_pSrcData = pSrcImage;
m_task.m_pDstData = pDstImage;
m_task.m_pResize = this;
return STS_OK;
}
Status ResizeImage(Image *pSrcImage, Image *pDstImage)
{
if(!pSrcImage || !pDstImage)
return STS_ERR_NULL_PTR;
if(m_templ != *pSrcImage)
{
Status status = Init(pSrcImage, pDstImage);
CHECK_STATUS_PRINT_RS(status, "Resize::Init()", GetBaseStatusString(status));
}
blocked_range2d<unsigned int, unsigned int> tbbRange(0, (unsigned int)pDstImage->m_size.height, m_iGrainY, 0, (unsigned int)pDstImage->m_size.width, m_iGrainX);
try
{
global_control set_num_threads(global_control::max_allowed_parallelism, m_iThreads);
parallel_for(tbbRange, m_task, m_part_auto);
}
catch(Status status)
{
return status;
}
return STS_OK;
}
private:
class ResizeTBBTask
{
public:
ResizeTBBTask() {};
void operator()(blocked_range2d<unsigned int, unsigned int> &r) const
{
IppStatus ippSts;
Status status;
Rect roi( (int)r.cols().begin(), (int)r.rows().begin(), r.cols().end() - r.cols().begin(), r.rows().end() - r.rows().begin() );
IppiSize dstRoiSize = {(int)roi.width, (int)roi.height};
IppiBorderType border = ippBorderRepl;
unsigned char *pBuffer = 0;
int iBufferSize;
ippSts = ippiResizeGetBufferSize_8u(m_pResize->m_pSpec, dstRoiSize, m_pSrcData->m_samples, &iBufferSize);
CHECK_STATUS_PRINT_AC(ippSts, "ippiResizeGetBufferSize_8u()", ippGetStatusString(ippSts), throw(STS_ERR_FAILED));
pBuffer = (unsigned char*)m_pResize->m_memPool.malloc(iBufferSize);
if(!pBuffer)
{
PRINT_MESSAGE("Cannot allocate memory for Resize buffer");
throw(STS_ERR_ALLOC);
}
status = m_pResize->ResizeBlock(m_pSrcData, m_pDstData, roi, border, pBuffer);
if(status != STS_OK)
throw(status);
m_pResize->m_memPool.free(pBuffer);
}
ResizeTBB *m_pResize;
Image *m_pSrcData;
Image *m_pDstData;
};
public:
unsigned int m_iGrainX;
unsigned int m_iGrainY;
private:
ResizeTBBTask m_task;
auto_partitioner m_part_auto;
memory_pool< scalable_allocator<unsigned char> > m_memPool;
};
#endif
int main(int argc, char *argv[])
{
/*
// Variables initialization
*/
Status status = STS_OK;
DString sInputFile = CheckTestDirs( BMP_GRAYSCALE_FILE );
DString sOutputFile;
char* sIppCpu = 0;
unsigned int iDstSize[2] = {0, 0};
#if defined(USE_TBB)
unsigned int iThreads = 0;
#else
unsigned int iThreads = 1;
#endif
unsigned int iInter = 1;
bool bAntiAliasing = false;
bool bNoAspect = false;
bool bNoWindow = false;
bool bPrintHelp = false;
// Cubic specific values
float fBVal = 1;
float fCVal = 0;
// Lanczos specific values
unsigned int iLobes = 3;
Image srcData;
Image dstData;
IppiInterpolationType interpolation;
int antiAliasing = 0;
Resize *pResize = 0;
// General timing
vm_tick tickStart = 0;
vm_tick tickAcc = 0;
vm_tick tickFreq = vm_time_get_frequency()/1000;
double fTime = 0;
unsigned int iTimeLimit = 0;
unsigned int iLoops = 0;
unsigned int iLoopsLimit = 0;
/*
// Cmd parsing
*/
const cmd::OptDef cmdOpts[] = {
{ 'i', "", 1, cmd::KT_DSTRING, cmd::KF_OPTIONAL, &sInputFile, "input file name" },
{ 'o', "", 1, cmd::KT_DSTRING, cmd::KF_OPTIONAL, &sOutputFile, "output file name" },
{ 'r', "", 2, cmd::KT_POSITIVE, 0, &iDstSize[0], "destination resolution (width height)" },
{ 'k', "", 1, cmd::KT_BOOL, 0, &bNoAspect, "do not keep aspect ratio" },
#if defined(USE_TBB)
{ 't', "", 1, cmd::KT_INTEGER, 0, &iThreads, "number of threads (0 - auto, 0 by default)" },
#endif
{ 'p', "", 1, cmd::KT_INTEGER, 0, &iInter, "interpolation:\n 0 - Nearest\n 1 - Linear (default)\n 2 - Cubic\n 3 - Lanczos" },
{ 'a', "", 1, cmd::KT_BOOL, 0, &bAntiAliasing, "use Anti Aliasing" },
#if defined(ENABLE_RENDERING)
{ 's', "", 1, cmd::KT_BOOL, 0, &bNoWindow, "suppress window output" },
#endif
{ 'w', "", 1, cmd::KT_POSITIVE, 0, &iTimeLimit, "minimum test time in milliseconds" },
{ 'l', "", 1, cmd::KT_POSITIVE, 0, &iLoopsLimit, "number of loops (overrides test time)" },
{ 'T', "", 1, cmd::KT_STRING, 0, &sIppCpu, "target Intel(R) IPP optimization (" IPP_OPT_LIST ")" },
{ 'h', "", 1, cmd::KT_BOOL, 0, &bPrintHelp, "print help and exit" },
{0}
};
if(cmd::OptParse(argc, argv, cmdOpts))
{
printHelp(cmdOpts, argv);
PRINT_MESSAGE("invalid input parameters");
return 1;
}
InitPreferredCpu(sIppCpu);
printVersion();
// Check default image availability
if ( !strcmp(sInputFile.c_str(), BMP_GRAYSCALE_FILE) ) {
bPrintHelp = ( -1 == vm_file_access(sInputFile.c_str(), 0) );
}
if(bPrintHelp)
{
printHelp(cmdOpts, argv);
return 0;
}
if(!sInputFile.Size())
{
printHelp(cmdOpts, argv);
PRINT_MESSAGE("Cannot open input file");
return 1;
}
if(iInter == CMD_INTER_NN)
interpolation = ippNearest;
else if(iInter == CMD_INTER_LIN)
interpolation = ippLinear;
else if(iInter == CMD_INTER_CUB)
interpolation = ippCubic;
else if(iInter == CMD_INTER_LAN)
{
interpolation = ippLanczos;
if(iLobes != 2 && iLobes != 3)
{
printHelp(cmdOpts, argv);
PRINT_MESSAGE("Invalid number of lobes");
return 1;
}
}
else
{
printHelp(cmdOpts, argv);
PRINT_MESSAGE("Invalid interpolation type");
return 1;
}
if (bAntiAliasing && (interpolation != ippNearest))
antiAliasing = 1;
for(;;)
{
// Read from file
printf("\nInput file: %s\n", sInputFile.c_str());
status = srcData.Read(sInputFile.c_str());
CHECK_STATUS_PRINT_BR(status, "Image::Read()", GetBaseStatusString(status));
printf("Input info: %dx%d %s\n", (int)srcData.m_size.width, (int)srcData.m_size.height, colorFormatName[srcData.m_color]);
// Prepare destination buffer
if(!iDstSize[0])
iDstSize[0] = (unsigned int)(srcData.m_size.width/2);
if(!iDstSize[1])
iDstSize[1] = (unsigned int)(srcData.m_size.height/2);
if(!iDstSize[0] || !iDstSize[1])
{
PRINT_MESSAGE("Invalid output resolution");
return 1;
}
dstData = srcData;
dstData.m_size.width = iDstSize[0];
dstData.m_size.height = iDstSize[1];
if(!bNoAspect)
{
double fXRatio = (double)dstData.m_size.width/srcData.m_size.width;
dstData.m_size.height = (unsigned int)ROUND_NEAR(srcData.m_size.height*fXRatio);
if(!dstData.m_size.height)
dstData.m_size.height = 1;
}
status = dstData.Alloc();
CHECK_STATUS_PRINT_BR(status, "Image::Alloc()", GetBaseStatusString(status));
printf("\nOutput file: %s\n", (sOutputFile.Size())?sOutputFile.c_str():"-");
printf("Output info: %dx%d %s\n", (int)dstData.m_size.width, (int)dstData.m_size.height, colorFormatName[dstData.m_color]);
if(iThreads == 1)
{
printf("\nSequential resize\n");
pResize = new Resize;
if(!pResize)
{
PRINT_MESSAGE("Failed to allocate sequential resize class");
return 1;
}
}
#ifdef USE_TBB
else
{
printf("\nTBB resize\n");
pResize = new ResizeTBB;
if(!pResize)
{
PRINT_MESSAGE("Failed to allocate Intel TBB resize class");
return 1;
}
pResize->m_iThreads = iThreads;
}
#endif
// pre-init
pResize->m_interpolation = interpolation;
pResize->m_antiAliasing = antiAliasing;
pResize->m_fBVal = fBVal;
pResize->m_fCVal = fCVal;
pResize->m_iLobes = iLobes;
status = pResize->Init(&srcData, &dstData);
CHECK_STATUS_PRINT_BR(status, "Resize::Init()", GetBaseStatusString(status));
if(iThreads != 1)
{
iThreads = pResize->m_iThreads;
printf("Threads: %d\n", iThreads);
}
printf("\nInterpolation: ");
if(iInter == CMD_INTER_NN)
printf("nearest\n");
else if(iInter == CMD_INTER_LIN)
printf("linear\n");
else if(iInter == CMD_INTER_CUB)
printf("cubic (B = %.2f; C = %.2f)\n", fBVal, fCVal);
else if(iInter == CMD_INTER_LAN)
printf("Lanczos (L = %d)\n", iLobes);
for(iLoops = 1, tickAcc = 0;; iLoops++)
{
tickStart = vm_time_get_tick();
status = pResize->ResizeImage(&srcData, &dstData);
tickAcc += (vm_time_get_tick() - tickStart);
CHECK_STATUS_PRINT_BR(status, "Resize::ResizeImage()", GetBaseStatusString(status));
fTime = (double)tickAcc/tickFreq;
if(iLoopsLimit)
{
if(iLoops >= iLoopsLimit)
break;
}
else
{
if(fTime >= (double)iTimeLimit)
break;
}
}
if(status < 0) break;
/*
// Results output
*/
printf("\nLoops: %d\n", iLoops);
printf("Time total: %0.3fms\n", fTime);
printf("Loop avg: %0.3fms\n", fTime/iLoops);
if(sOutputFile.Size())
{
status = dstData.Write(sOutputFile.c_str());
CHECK_STATUS_PRINT_BR(status, "Image::Write()", GetBaseStatusString(status));
}
// Rendering
if(!bNoWindow)
{
WindowDraw draw("Intel(R) IPP Resize example", WF_FIT_TO_IMAGE);
if(draw.IsInitialized())
{
printf("\nPress Space to cycle through stages:\n");
printf("1 - result image\n");
printf("2 - original image\n");
printf("\nClose window to exit.\n");
int iIndex = 0;
bool bRedraw = true;
while(!draw.IsClosed())
{
vm_time_sleep(10);
if(draw.CheckKey() == KK_SPACE)
{
iIndex = (iIndex+1)%2;
bRedraw = true;
}
if(draw.IsInvalidated())
bRedraw = true;
if(bRedraw)
{
if(iIndex == 0)
draw.DrawImage(&dstData);
else if(iIndex == 1)
draw.DrawImage(&srcData);
bRedraw = false;
}
}
}
}
break;
}
if(pResize) delete pResize;
if(status < 0)
return status;
return 0;
}