Question

I'm working on a Cocoa OS X program to clean up scanned pages and would like to use Leptonica's library to do the heavy lifting. I've found some info in this post, this one, and this one. I can certainly get a CGImage from the NSImage and can write data to a Leptonica Pix image. The problem I have is that 75% of the time my image comes out warped with a barbershop pole type pattern (each successive row of pixels from the top to the bottom of the image is shifted farther and farther to the right). Sometimes though the picture comes out fine. I assume that I am doing something wrong in seting up the image data, but it's not really my forte so I'm having trouble understanding the issue. I'm creating the Pix image using the following code:

CGImageRef myCGImage = [processedImage CGImageForProposedRect:NULL context:NULL hints:NULL];
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(myCGImage));
const UInt8 *imageData = CFDataGetBytePtr(data);

Pix *myPix = (Pix *) malloc(sizeof(Pix));
myPix->w = (int)CGImageGetWidth (myCGImage);
myPix->h = (int)CGImageGetHeight (myCGImage);
myPix->d = (int)CGImageGetBitsPerPixel(myCGImage);
myPix->wpl =  ((CGImageGetWidth (myCGImage)*CGImageGetBitsPerPixel(myCGImage))+31)/32;
myPix->informat = IFF_TIFF;
myPix->data = (l_uint32 *) imageData;
myPix->colormap = NULL;

The pix struct is defined as follows:

/*-------------------------------------------------------------------------*
 *                              Basic Pix                                  *
 *-------------------------------------------------------------------------*/
struct Pix
{
uint32             w;           /* width in pixels                   */
uint32             h;           /* height in pixels                  */
uint32             d;           /* depth in bits                     */
uint32             wpl;         /* 32-bit words/line                 */
uint32             refcount;    /* reference count (1 if no clones)  */
int              xres;        /* image res (ppi) in x direction    */
                                  /* (use 0 if unknown)                */
int              yres;        /* image res (ppi) in y direction    */
                                  /* (use 0 if unknown)                */
int              informat;    /* input file format, IFF_*          */
char                *text;        /* text string associated with pix   */
struct PixColormap  *colormap;    /* colormap (may be null)            */
uint32            *data;        /* the image data                    */
};
Was it helpful?

Solution

The "barbershop pole type pattern" is a classic sign of having the wrong number of bytes per row of pixel data.

You should base wpl on the value returned by CGImageGetBytesPerRow. Most likely:

myPix->wpl = CGImageGetBytesPerRow(myCGImage) / 4;

There are several reasons why the image's bytes-per-row would differ from your guess based on CGImageGetWidth(). For instance, it might be rounded up for performance reasons, or the image might be a sub-image of a wider image.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top