• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: vImage Help
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: vImage Help


  • Subject: Re: vImage Help
  • From: "Adam R. Maxwell" <email@hidden>
  • Date: Sat, 14 Nov 2009 13:40:59 -0800

On Nov 14, 2009, at 1:01 PM, R T wrote:

> I'm using... vImage_Error err = vImageContrastStretch_Planar8 (&src, &dest, flags  );
>
> and getting a scrambled image from the code? Each pixel returned is at the right height but offset left 3 pixels. Anyone wanting to you to look the images email me.
>
> - (NSImage*)vImageContrastStretch:(NSImage*)anImage{
> NSBitmapImageRep *anImageRep = [[NSBitmapImageRep alloc] initWithData:[anImage TIFFRepresentation]];

TIFFRepresentation is slow.  Here you'd be better off to choose a fixed pixel format and draw the NSImage into a new NSBitmapImageRep that you control.  This will almost certainly bite you later on...especially if you switch architectures and the order changes from ARGB to RGBA.

> unsigned char *inBytes = [anImageRep bitmapData];
> NSSize imageSize = [anImage size];
> UInt32 imageWidth = imageSize.width;
> UInt32 imageHeight = imageSize.height;

Here you want to use pixelsWide and pixelsHigh, and note that they are typed NSInteger, not uint32_t.

> NSImage *newImage = [[[NSImage alloc] initWithSize:imageSize]autorelease];
> NSBitmapImageRep *newImageRep;
> UInt32 samplesPerPixel = [anImageRepsamplesPerPixel];
>        BOOL hasAlpha;
> if (samplesPerPixel==2 || samplesPerPixel==4) { // Gray+alpha or RGBA?
> hasAlpha = YES;
> } else {
> hasAlpha = NO;
> }
> NSString *colorSpaceName = nil;
> if (samplesPerPixel==1 || samplesPerPixel==2) { // Gray or Gray+alpha?
> colorSpaceName = NSCalibratedWhiteColorSpace;
> } else if (samplesPerPixel==3 || samplesPerPixel==4) { // RGB or RGBA?
> colorSpaceName = NSCalibratedRGBColorSpace;
> } else {NSLog(@"I can't handle a colorspace with %d samples per pixel",samplesPerPixel);
> return nil;}
> newImageRep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
>       pixelsWide:imageWidth
>       pixelsHigh:imageHeight
>    bitsPerSample:8
> samplesPerPixel:samplesPerPixel
> hasAlpha:hasAlpha
> isPlanar:NO
>   colorSpaceName:colorSpaceName
>      bytesPerRow:0
>     bitsPerPixel:0] autorelease];
> unsigned char *outBytes = [newImageRep bitmapData];
> long numPixels = imageWidth * imageHeight;
> unsigned char *workBuffer1 = malloc(numPixels*sizeof(char));
> unsigned char *workBuffer2 = malloc(numPixels*sizeof(char));
> if (workBuffer1==NULL || workBuffer2==NULL) {NSLog(@"Can't allocate memory for image ");
> return nil;}
> vImage_Flags flags = 1;

Use the named constant: kvImageLeaveAlphaUnchanged.

> int sampleIx;
> for (sampleIx=0; sampleIx<samplesPerPixel; sampleIx++) {
> int ix; for (ix=0; ix<numPixels; ix++) *(workBuffer1+ix) = *(inBytes + ix*samplesPerPixel + sampleIx);
>
> const vImage_Buffer src = { workBuffer1, imageHeight, imageWidth, imageWidth*sizeof(char) };
> const vImage_Buffer dest = { workBuffer2, imageHeight, imageWidth, imageWidth*sizeof(char) };
>
> vImage_Error err = vImageContrastStretch_Planar8 (&src, &dest, flags  );

How are you avoiding stretching the alpha channel?  Shouldn't you skip it manually?

> if (err!=kvImageNoError) {return nil;}
> for (ix=0; ix<numPixels; ix++) *(outBytes + ix*samplesPerPixel + sampleIx) = *(workBuffer2+ix);
> }

Since you passed 0 when creating the image rep, NSBitmapImageRep will pad rows as it sees fit.  You need to compute the start of each row using -bytesPerRow, which is likely producing the offset you see.

If you always created an ARGB image and set the image rep bytesPerRow parameter yourself (or ensure it's the same for source and destination), you could use vImageContrastStretch_ARGB8888 and fill out the vImage_Buffer of the source and destination using [imageRep bitmapData] as the buffer.  That would also avoid all of the copies you're doing.  Even better, look for a way to do this using Core Image; vImage is tricky to use with Cocoa graphics objects, in my opinion.

Sorry if I misread anything here...your indentation and bracket style isn't what I'm used to.


Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >vImage Help (From: R T <email@hidden>)

  • Prev by Date: vImage Help
  • Next by Date: Fwd: retain and don`t retain in accessor methods
  • Previous by thread: vImage Help
  • Next by thread: Fwd: retain and don`t retain in accessor methods
  • Index(es):
    • Date
    • Thread