void doIndexedColorDrawGraphics(CGContextRef context)
{
	CGColorSpaceRef theBaseRGBSpace = getTheCalibratedRGBColorSpace();
	CGColorSpaceRef theIndexedSpace = NULL;
	unsigned char lookupTable[6];
	float opaqueRed[] = { 0, 1 }; // index, alpha
	float aBlue[] = { 1, 1 };   // index, alpha
	
	// Set the first 3 values in the lookup table to a red of
	// 169/255 = 0.663, no green, and blue = 8/255 = 0.031. This makes  
	// the first entry in the lookup table a shade of red.
	lookupTable[0] = 169; lookupTable[1] = 0; lookupTable[2] = 8;
	
	// Set the second 3 values in the lookup table to a red value
	// of 123/255 = 0.482, a green value of 158/255 = 0.62, and
	// a blue value of 222/255 = 0.871. This makes the second entry
	// in the lookup table a shade of blue.
	lookupTable[3] = 123; lookupTable[4] = 158; lookupTable[5] = 222;
	
	// Create the indexed color space with this color lookup table,
	// using the RGB color space as the base color space and a 2 element
	// color lookup table to characterize the indexed color space.
	theIndexedSpace = CGColorSpaceCreateIndexed(theBaseRGBSpace, 1, lookupTable);
	if(theIndexedSpace != NULL){
	    CGContextSetStrokeColorSpace(context, theIndexedSpace);
	    CGContextSetFillColorSpace(context, theIndexedSpace);
	    // Release the color space this code created since it is no
		// longer needed in this routine.
	    CGColorSpaceRelease(theIndexedSpace);

	    // Set the stroke color to an opaque blue.
	    CGContextSetStrokeColor(context, aBlue);
	    // Set the fill color to an opaque red.
	    CGContextSetFillColor(context, opaqueRed);

	    CGContextSetLineWidth(context, 8.);
	 	// Draw the first rectangle.
	    CGContextBeginPath(context);
	    CGContextAddRect(context, CGRectMake(20., 20., 100., 100.));
	    CGContextDrawPath(context, kCGPathFillStroke);

	    // Continue to use the stroke colorspace already set
	    // but change the stroke alpha value to a semitransparent value
	    // while leaving the index value unchanged.
	    aBlue[1] = 0.5;
	    CGContextSetStrokeColor(context, aBlue);
	    // Draw another rectangle to the right of the first one.
	    CGContextBeginPath(context);
	    CGContextAddRect(context, CGRectMake(140., 20., 100., 100.));
	    CGContextDrawPath(context, kCGPathFillStroke);
	}else
	    fprintf(stderr, "Couldn't make the indexed color space!\n");
}
Esempio n. 2
0
CGColorSpaceRef colorSpaceFromPDFArray(CGPDFArrayRef colorSpaceArray){
	CGColorSpaceRef       cgColorSpace = NULL, alternateColorSpace = NULL;
	CGPDFStreamRef        stream;
	const char            *colorSpaceName = NULL, *alternateColorSpaceName = NULL;
	CGPDFInteger        numberOfComponents;
	CGPDFDictionaryRef    dict;
	bool                retrieved;
	CGFloat                *range;
	CGPDFArrayRef        rangeArray;
	
	if (CGPDFArrayGetName(colorSpaceArray, 0, &colorSpaceName)) {
		if (strcmp(colorSpaceName, "ICCBased") == 0) {
			if (CGPDFArrayGetStream(colorSpaceArray, 1, &stream)) {
				dict = CGPDFStreamGetDictionary(stream);
				
				// First obtain the alternate color space if present
				if (CGPDFDictionaryGetName(dict, "Alternate",  &alternateColorSpaceName)) {
					if (strcmp(alternateColorSpaceName, "DeviceRGB") == 0) {
						alternateColorSpace = CGColorSpaceCreateDeviceRGB();
					} else if (strcmp(alternateColorSpaceName, "DeviceGray") == 
							   0) {
						alternateColorSpace = CGColorSpaceCreateDeviceGray();
					} else if (strcmp(alternateColorSpaceName, "DeviceCMYK") == 
							   0) {
						alternateColorSpace = CGColorSpaceCreateDeviceCMYK();
					}
				}
				
				// Obtain the preferential color space
				CGPDFDataFormat        dataFormat;
				CFDataRef            colorSpaceDataPtr = 
				CGPDFStreamCopyData(stream, &dataFormat);
				
				if (dataFormat == CGPDFDataFormatRaw) {
					CGDataProviderRef    profile = 
					CGDataProviderCreateWithCFData(colorSpaceDataPtr);
					
					retrieved = CGPDFDictionaryGetInteger(dict, "N", 
														  &numberOfComponents);
					
					// Deduce an alternate color space if we don't have one 
					//already
					if (alternateColorSpace == NULL) {
						switch (numberOfComponents) {
							case 1:
								alternateColorSpace = CGColorSpaceCreateDeviceGray();
								break;
							case 3:
								alternateColorSpace = CGColorSpaceCreateDeviceRGB();
								break;
							case 4:
								alternateColorSpace = CGColorSpaceCreateDeviceCMYK();
								break;
							default:
								break;
						}
					}
					
					range = malloc(numberOfComponents * 2 * sizeof(CGFloat));
					if (!CGPDFDictionaryGetArray(dict, "Range", &rangeArray)) {
						int i = 0;
						for (; i < numberOfComponents * 2; i += 2) {
							range[i] = (i % 2 == 0) ? 0.0 : 1.0;
						}
					} else {
						size_t count = CGPDFArrayGetCount(rangeArray);
						int i = 0;
						for (; i < count; i++) {
							(void)CGPDFArrayGetNumber(rangeArray, i, &range[i]);
						}
						
					}
					
					
					cgColorSpace = CGColorSpaceCreateICCBased(numberOfComponents, range, profile, 
															  alternateColorSpace);
					CGDataProviderRelease(profile);
					free(range);
					if (cgColorSpace) {
						// Since we have a preferential color space, we no 
						//longer need the hang on to the alternate color space
						CGColorSpaceRelease(alternateColorSpace);
					} else {
						cgColorSpace = alternateColorSpace;
					}
					
				} else if (dataFormat == CGPDFDataFormatJPEGEncoded) {
					//
				} else if (dataFormat == CGPDFDataFormatJPEG2000) {
					//
				}
			}
		} else if (strcmp(colorSpaceName, "Indexed") == 0) {
			CGColorSpaceRef baseSpace;
			CGPDFArrayRef    base = NULL;
			CGPDFInteger    highValue = 0;
			CGPDFStreamRef    stream = NULL;
			CGPDFStringRef    string;
			const unsigned char *chars;
			const char        *namedColorSpaceName;
			
			if (CGPDFArrayGetArray(colorSpaceArray, 1, &base)) {
				baseSpace = colorSpaceFromPDFArray(base);
			} else if (CGPDFArrayGetName(colorSpaceArray, 1, 
										 &namedColorSpaceName)) {
				if (strcmp(namedColorSpaceName, "DeviceRGB") == 0) {
					baseSpace = CGColorSpaceCreateDeviceRGB();
				} else if (strcmp(namedColorSpaceName, "DeviceGray") == 0) {
					baseSpace = CGColorSpaceCreateDeviceGray();
				} else if (strcmp(namedColorSpaceName, "DeviceCMYK") == 0) {
					baseSpace = CGColorSpaceCreateDeviceCMYK();
				}
			}
			
			retrieved = CGPDFArrayGetInteger(colorSpaceArray, 2, &highValue);
			
			if (CGPDFArrayGetStream(colorSpaceArray, 3, &stream)) {
				chars = CFDataGetBytePtr(CGPDFStreamCopyData(stream, NULL));
			} else if (CGPDFArrayGetString(colorSpaceArray, 3, &string)) {
				chars = CGPDFStringGetBytePtr(string);
			} else {
				
				// TODO: Raise some error state?
			}
			
			cgColorSpace = CGColorSpaceCreateIndexed(baseSpace, highValue, 
													 chars);
		}
	}
	
	return (CGColorSpaceRef)CFMakeCollectable(cgColorSpace);
}
Esempio n. 3
0
CGColorSpaceRef CGColorSpaceCreateIndexed_wrap(CGColorSpaceRef base, u_char* table, uint32 len ) {
  return CGColorSpaceCreateIndexed(base, len, table);
}