Skip to content

Commit

Permalink
Optimization to remove an unnecessary memcpy() of pixel data. JPEGVie…
Browse files Browse the repository at this point in the history
…w allocates and frees the memory instead of calling avifRGBImageAllocatePixels/avifRGBImageFreePixels

Merge PR #208 by https://github.com/qbnu
  • Loading branch information
sylikc committed Jun 15, 2023
2 parents d3dc3e3 + 13a261b commit 8f92b8b
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions src/JPEGView/AVIFWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ void* AvifReader::ReadImage(int& width,
width = height = 0;
nchannels = 4;
has_animation = false;
unsigned char* pPixelData = NULL;

avifResult result;
int nthreads = 256; // sets maximum number of active threads allowed for libavif, default is 1
Expand Down Expand Up @@ -70,12 +69,6 @@ void* AvifReader::ReadImage(int& width,
cache.rgb.depth = 8;
cache.rgb.format = AVIF_RGB_FORMAT_BGRA;
cache.rgb.maxThreads = nthreads;
avifRGBImageAllocatePixels(&cache.rgb);
result = avifImageYUVToRGB(cache.decoder->image, &cache.rgb);
if (result != AVIF_RESULT_OK) {
DeleteCache();
return NULL;
}

width = cache.rgb.width;
height = cache.rgb.height;
Expand All @@ -84,24 +77,28 @@ void* AvifReader::ReadImage(int& width,
frame_time = (int)(cache.decoder->imageTiming.duration * 1000.0);

size_t size = width * nchannels * height;
pPixelData = new(std::nothrow) unsigned char[size];
if (pPixelData == NULL) {
cache.rgb.pixels = new(std::nothrow) unsigned char[size];
if (cache.rgb.pixels == NULL) {
outOfMemory = true;
return NULL;
}
cache.rgb.rowBytes = width * nchannels;
result = avifImageYUVToRGB(cache.decoder->image, &cache.rgb);
if (result != AVIF_RESULT_OK) {
delete[] cache.rgb.pixels;
DeleteCache();
return NULL;
}
avifRWData icc = cache.decoder->image->icc;
if (cache.transform == NULL)
cache.transform = ICCProfileTransform::CreateTransform(icc.data, icc.size, ICCProfileTransform::FORMAT_BGRA);
if (!ICCProfileTransform::DoTransform(cache.transform, cache.rgb.pixels, pPixelData, width, height))
memcpy(pPixelData, cache.rgb.pixels, size);
avifRGBImageFreePixels(&cache.rgb);
ICCProfileTransform::DoTransform(cache.transform, cache.rgb.pixels, cache.rgb.pixels, width, height);
if (!has_animation)
DeleteCache();
return pPixelData;
return cache.rgb.pixels;
}

void AvifReader::DeleteCache() {
avifRGBImageFreePixels(&cache.rgb);
if (cache.decoder)
avifDecoderDestroy(cache.decoder);
free(cache.data);
Expand Down

0 comments on commit 8f92b8b

Please sign in to comment.