The following code snippet reads a JPEG file into memory, does Cubic resize halfing by 2 with Intel IPP and then writes the resized memory blob into a different JPEG file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipp.h>
int main(int argc, char **argv)
{
if (argc != 4) {
fprintf(stderr, "usage: %s <filename> <width> <height>n", argv[0]);
exit(EXIT_FAILURE);
}
ippInit();
const char *src_name = argv[1];
FILE *src_file = fopen(src_name, "rb");
if (src_file == NULL) {
perror("fopen()");
exit(EXIT_FAILURE);
}
if (fseek(src_file, 0, SEEK_END) == -1) {
perror("fseek()");
exit(EXIT_FAILURE);
}
long src_len = ftell(src_file);
if (src_len == -1) {
perror("ftell()");
exit(EXIT_FAILURE);
}
rewind(src_file);
Ipp8u *srcIpp = (Ipp8u *) ippsMalloc_8u(src_len);
if (srcIpp == NULL) {
fprintf(stderr, "There is not enough memory for allocating srcIppn");
exit(EXIT_FAILURE);
}
if (fread(srcIpp, src_len, 1, src_file) == -1) {
perror("fread()");
exit(EXIT_FAILURE);
}
if (fclose(src_file) == EOF) {
perror("fclose()");
exit(EXIT_FAILURE);
}
const size_t src_width = (size_t) atol(argv[2]);
const size_t src_height = (size_t) atol(argv[3]);
const size_t dst_width = (size_t) src_width / 2;
const size_t dst_height = (size_t) src_height / 2;
const short num_channels = 3;
Ipp8u *dstIpp = (Ipp8u *) ippsMalloc_8u(dst_width * dst_height * num_channels);
if (dstIpp == NULL) {
fprintf(stderr, "There is not enough memory for allocating dstIppn");
exit(EXIT_FAILURE);
}
IppiResizeSpec_32f *ippSpec = 0;
int specSize = 0, initSize = 0, bufSize = 0;
Ipp8u *ippBuffer = 0;
Ipp8u *initBuf = 0;
Ipp32u numChannels = 3;
IppiPoint dstOffset = { 0, 0 };
IppiBorderType border = ippBorderDefault;
int srcStep = src_width * 3;
int dstStep = dst_width * 3;
IppiSize srcSize = { src_width, src_height };
IppiSize dstSize = { dst_width, dst_height };
IppStatus ippStatus;
ippStatus = ippiResizeGetSize_8u(srcSize, dstSize, ippCubic, 0, &specSize, &initSize);
if (ippStatus != ippStsNoErr) {
fprintf(stderr, "ippiResizeGetSize_8u(): %sn", ippGetStatusString(ippStatus));
exit(EXIT_FAILURE);
}
initBuf = (Ipp8u *) ippsMalloc_8u(initSize);
if (initBuf == NULL) {
fprintf(stderr, "There is not enough memory for allocating initBufn");
exit(EXIT_FAILURE);
}
ippSpec = (IppiResizeSpec_32f *) ippsMalloc_8u(specSize);
if (ippSpec == NULL) {
fprintf(stderr, "There is not enough memory for allocating ippSpecn");
exit(EXIT_FAILURE);
}
ippStatus = ippiResizeCubicInit_8u(srcSize, dstSize, 1, 1, ippSpec, initBuf);
if (ippStatus != ippStsNoErr) {
fprintf(stderr, "ippiResizeCubicInit_8u(): %sn", ippGetStatusString(ippStatus));
exit(EXIT_FAILURE);
}
ippsFree(initBuf);
ippStatus = ippiResizeGetBufferSize_8u(ippSpec, dstSize, numChannels, &bufSize);
if (ippStatus != ippStsNoErr) {
fprintf(stderr, "ippiResizeGetBufferSize_8u(): %sn", ippGetStatusString(ippStatus));
exit(EXIT_FAILURE);
}
ippBuffer = (Ipp8u *) ippsMalloc_8u(bufSize);
if (ippBuffer == NULL) {
fprintf(stderr, "There is not enough memory for allocating ippBuffern");
exit(EXIT_FAILURE);
}
ippStatus = ippiResizeCubic_8u_C3R(srcIpp, srcStep, dstIpp, dstStep, dstOffset, dstSize, border, 0, ippSpec, ippBuffer);
if (ippStatus != ippStsNoErr) {
fprintf(stderr, "ippiResizeCubic_8u_C3R(): %sn", ippGetStatusString(ippStatus));
exit(EXIT_FAILURE);
}
FILE *dst_file = fopen("IPP.JPG", "wb");
if (dst_file == NULL) {
perror("fopen()");
exit(EXIT_FAILURE);
}
if (fwrite(dstIpp, sizeof(*dstIpp), 1, dst_file) == -1) {
perror("fwrite()");
exit(EXIT_FAILURE);
}
if (fclose(dst_file) == EOF) {
perror("fclose()");
exit(EXIT_FAILURE);
}
ippsFree(ippSpec);
ippsFree(ippBuffer);
ippsFree(srcIpp);
ippsFree(dstIpp);
exit(EXIT_SUCCESS);
}
But the following error arises:
ippiResizeCubic_8u_C3R(): ippStsBorderErr: Illegal value for border type
and if I change the border type to ippBorderConst
I get the following:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==18018==ERROR: AddressSanitizer: SEGV on unknown address 0x799774aa64c0 (pc 0x79976e59e807 bp 0x000000000000 sp 0x7ffe382618b0 T0)
==18018==The signal is caused by a READ memory access.
#0 0x79976e59e807 in l9_ownCalcBorderR3Cubic8u (/opt/intel/oneapi/ipp/2021.11/lib/libippil9.so.10.10+0x139e807)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/opt/intel/oneapi/ipp/2021.11/lib/libippil9.so.10.10+0x139e807) in l9_ownCalcBorderR3Cubic8u
==18018==ABORTING
Code was compiled with:
gcc -std=c11 -fsanitize=address -g -o test test.c -I/opt/intel/oneapi/ipp/2021.11/include/ -L/opt/intel/oneapi/ipp/2021.11/lib/ -lippcore -lipps -lippi
and run with:
LD_LIBRARY_PATH=/opt/intel/oneapi/ipp/2021.11/lib/ ./test <filename> <width> <height>
Some suggestions ?
Gianluca