Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

dearvivekkumar

macrumors newbie
Original poster
Jan 3, 2011
9
0
New Delhi, India
Code:
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, [COLOR="Red"]quadBytes[/COLOR], rowBytes * height, NULL);

I am not getting how to create DataProvide if I have RBG value. RGB value is in structure like below. As i am porting from window os to mac.

Code:
typedef struct tagRGBQUAD { 
	unsigned char  rgbBlue;
	unsigned char  rgbGreen;
	unsigned char  rgbRed;
	unsigned char  rgbReserved;
} RGBQUAD;

please guide me. Any clue will be highly appreciated.

Thanks.
 

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
I've never used that function, but I suspect it is looking for an array based on the next argument to the size.

So the struct is close, (although the last byte should probably be alpha) and may compile with a size of 1.
 

dearvivekkumar

macrumors newbie
Original poster
Jan 3, 2011
9
0
New Delhi, India
Thanks for your reply

Yeah i am passing quadBytes which is containg the channel pixel data is that what required or something else. If yes, then how would i arrange my pixel data for passing to the CGDataProvider.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
I've never done this, but I don't think you'll be able get a data provider for raw bitmap data like this. As I understand it, one of things CGDataProviderCreateWithData is going to do is analyse the data to try to determine it's format (JPEG, PNG, TIFF, etc.).

Again I've never done this, but it sounds to me you might need to create a custom data provider via CGDataProviderCreateDirect or CGDataProviderCreateSequential. Or perhaps you could wrap your raw data in an image container format first (TIFF would probably be the easiest) and then use CGDataProviderCreateWithData.

The Quartz 2D Programming Guide in the documentation as chapters on data management and bitmap images. Perhaps these might shed some light.

However if your ultimate goal is just to display the bitmap, perhaps a custom view which draw the bitmap might be the easiest approach.
 

dearvivekkumar

macrumors newbie
Original poster
Jan 3, 2011
9
0
New Delhi, India
@jiminaus

Actually i am very new to image graphics type programming. I am trying to create a photoshop plug-in, which i have to export every layers in a corresponding image file.
For that I have gathered the layer data in structure I have posted in my earlier post and that is working well and nice in win os as i had first tried in win os.
Now i am doing the same for mac os using carbon framework and definitely Quartz, so as for now i have the layer data which is RGB and alpha components for which i wants to create a image for that i need to create a pixel in that image.
I have read the quartz 2d programming documentation, i that i have to provide the color spaces for data i need to provide the data which i created through the data provider and as it to opaque i am not getting how the pixel data(ie the RGB layer components and the alpha components) is created with the data provider.

so here i am stuck how would i provide the data which i have collected in the structure (named rgbQuard which i have mentioned in my earlier post) form???
If am wrong somewhere is my process of creating the data advice will be greatly appreciated.

Thanks​
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
The code below creates a CGImage from your raw layer data and then outputs it to an uncompressed TIFF file.

You can specify many options for the output file. Have a look at the Image I/O programming guide and the CGImageProperties reference.

You can output to a different type of file by changing the image type in the call to CGImageDestinationCreateWithURL. A list of pre-declared UTI's is in the Uniform Type Identifiers reference.

Code:
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

typedef struct tagRGBQUAD {
	unsigned char rgbBlue;
	unsigned char rgbGreen;
	unsigned char rgbRed;
	unsigned char rgbReserved;
} RGBQUAD;

RGBQUAD *makeLayer(size_t xSize, size_t ySize) {
	assert(ySize % 3 == 0);        /* This code only works when ySize is a multiple of 3 */
	assert(sizeof(RGBQUAD) == 4);  /* And when sizeof(RGBQUAD) is 4 */
	RGBQUAD *layer = malloc(sizeof(RGBQUAD) * xSize * ySize);
	const size_t rowSize = sizeof(RGBQUAD) * xSize;
	RGBQUAD *row = malloc(rowSize);
	const size_t bandSize = ySize / 3;
	size_t y = 0;
	/* Make a band of blue */
	memset(row, 0, sizeof(RGBQUAD));
	row->rgbBlue = 255;
	memset_pattern4(row + 1, row, rowSize - sizeof(RGBQUAD));
	for (; y < bandSize; ++y) {
		memcpy(layer + (y * xSize), row, sizeof(RGBQUAD) * xSize);
	}
	/* Make a band of green */
	memset(row, 0, sizeof(RGBQUAD));
	row->rgbGreen = 255;
	memset_pattern4(row + 1, row, rowSize - sizeof(RGBQUAD));
	for (; y < bandSize * 2; ++y) {
		memcpy(layer + (y * xSize), row, sizeof(RGBQUAD) * xSize);
	}
	/* Make a band of red */
	memset(row, 0, sizeof(RGBQUAD));
	row->rgbRed = 255;
	memset_pattern4(row + 1, row, rowSize - sizeof(RGBQUAD));
	for (; y < ySize; ++y) {
		memcpy(layer + (y * xSize), row, sizeof(RGBQUAD) * xSize);
	}	
	free(row);
	return layer;
}

CGImageRef makeImageFromLayer(RGBQUAD *layer, size_t xSize, size_t ySize) {
	CGDataProviderRef provider =
		CGDataProviderCreateWithData(NULL, layer, sizeof(RGBQUAD) * xSize * ySize, NULL);
	CGColorSpaceRef colorSpace = 
		CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
	CGImageRef image =
		CGImageCreate(xSize, ySize, 8, 32, sizeof(RGBQUAD) * xSize,
                              colorSpace, kCGBitmapByteOrderDefault, provider,
                              NULL, FALSE, kCGRenderingIntentDefault);
	CFRelease(provider);
	CFRelease(colorSpace);
	return image;
}

void writeImageToPath(CGImageRef layerImage, const char* path) {
	CFStringRef pathString =
		CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
	CFURLRef url =
		CFURLCreateWithFileSystemPath(NULL, pathString, kCFURLPOSIXPathStyle, false);	

	CFDictionaryRef options =
		CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL);
	
	CGImageDestinationRef imageDest =
		CGImageDestinationCreateWithURL(url, kUTTypeTIFF, 1, NULL);
	CGImageDestinationAddImage(imageDest, layerImage, options);
	CGImageDestinationFinalize(imageDest);
	
	CFRelease(imageDest);
	CFRelease(options);
	CFRelease(url);
	CFRelease(pathString);
}

int main (int argc, const char *argv[]) {	
	const size_t xSize = 96;
	const size_t ySize = 96;
	const char *outputPath = "/tmp/a.tiff";
	RGBQUAD *layer = makeLayer(xSize, ySize);
	CGImageRef layerImage = makeImageFromLayer(layer, xSize, ySize);
	writeImageToPath(layerImage, outputPath);
	CFRelease(layerImage);
	free(layer);
    return 0;	
}
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.