Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Performing a costly unpadding operation!" -- what is it, and how to fix it?

The debug console for my Core Filters test application is showing this message:

CGImageRef 0x7a0e890 has row byte padding. Performing a costly unpadding operation!

I couldn't find a hit for that exact message (minus the pointer info) in the headers or in a Google search.

My questions are (1)what does that mean and (2)how can I rectify the situation?

The following is an example of how I am generating a filtered UIImage using a CIFilter.

- (UIImage*)sepia
{    
    CIImage *beginImage = [CIImage imageWithCGImage:[self CGImage]];
    CIContext *context = [CIContext contextWithOptions:nil];

    CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" 
                                  keysAndValues: kCIInputImageKey, beginImage, 
                        @"inputIntensity", [NSNumber numberWithFloat:0.8], nil];
    CIImage *outputImage = [filter outputImage];

    CGImageRef cgimg = 
    [context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *newImg = [UIImage imageWithCGImage:cgimg];

    self = newImg;

    CGImageRelease(cgimg);
    return self;
}
like image 923
james_womack Avatar asked Nov 17 '11 19:11

james_womack


2 Answers

Byte padding is extra bytes added to the end of each image row to ensure that each row starts on a 2^n byte multiple in memory. This increases memory access performance at the expense of image size. You can check this if you compare the result of CGImageGetBytesPerRow and the expected bytes per row calculated from the image dimensions and bytes per pixel.

As to how to rectify the unpadding - you need to find exactly which operation is triggering the unpadding and take it from there. Unpadding is expensive because basically the whole image memory needs to be shuffled up to remove all the end-of-row gaps.

like image 136
Robin Summerhill Avatar answered Sep 30 '22 00:09

Robin Summerhill


I would write a comment, but since I cannot do this due to the low reputation I've got, I'll post it as an answer here:

I just had the same error and tried to fix it by using Thuggish Nuggets' suggestion. Turned out it's the right approach, however the image size has to be a multitude of 8. I just aligned the width to the multitude of 8, I don't know if the height also has to be a multitude of 8 since the image I tested this approach with was quadratic anyways.

Here's the (probably not very efficient) algorithm to give you a basic idea on how to calculate the needed size:

UIImage *image = ...;
CGSize targetSize = image.frame.size; //e.g. 51 x 51
double aspectRatio = targetSize.width / targetSize.height;
targetSize.width = targetSize.width + 8 - ((int)targetSize.width % 8);
targetSize.height = targetSize.width / aspectRatio;
like image 33
Florian Avatar answered Sep 29 '22 23:09

Florian