Example #1
0
static int add_png_to_family(icns_family_t **iconFamily, char *pngname)
{
	FILE *pngfile;

	int icnsErr = ICNS_STATUS_OK;
	icns_image_t icnsImage;
	icns_image_t icnsMask;
	icns_type_t iconType;
	icns_type_t maskType;
	icns_icon_info_t iconInfo;

	icns_element_t *iconElement = NULL;
	icns_element_t *maskElement = NULL;
	char iconStr[5] = {0,0,0,0,0};
	char maskStr[5] = {0,0,0,0,0};
	int iconDataOffset = 0;
	int maskDataOffset = 0;
    
    char isHiDPI = 0;
    
    int pngnamelen = strlen(pngname);
    int namea2xpng = pngnamelen - 7;

	png_bytep buffer;
	int width, height, bpp;
    
	if(namea2xpng > 0) {
			if(memcmp(&pngname[namea2xpng],"@2x.png",7) == 0) {
					isHiDPI = 1;
			}
			if(memcmp(&pngname[namea2xpng],"@2X.PNG",7) == 0) {
					isHiDPI = 1;
			}
	}
    
	pngfile = fopen(pngname, "rb");
	if (pngfile == NULL)
	{
		fprintf(stderr, "Could not open '%s' for reading: %s\n", pngname, strerror(errno));
		return FALSE;
	}

	if (!read_png(pngfile, &buffer, &bpp, &width, &height))
	{
		fprintf(stderr, "Failed to read PNG file\n");
		fclose(pngfile);

		return FALSE;
	}

	fclose(pngfile);

	icnsImage.imageWidth = width;
	icnsImage.imageHeight = height;
	icnsImage.imageChannels = 4;
	icnsImage.imagePixelDepth = 8;
	icnsImage.imageDataSize = width * height * 4;
	icnsImage.imageData = buffer;

	iconInfo.isImage = 1;
	iconInfo.iconWidth = icnsImage.imageWidth;
	iconInfo.iconHeight = icnsImage.imageHeight;
	iconInfo.iconBitDepth = bpp;
	iconInfo.iconChannels = (bpp == 32 ? 4 : 1);
	iconInfo.iconPixelDepth = bpp / iconInfo.iconChannels;

	iconType = icns_get_type_from_image_info_advanced(iconInfo,isHiDPI);
	maskType = icns_get_mask_type_for_icon_type(iconType);

	icns_type_str(iconType,iconStr);
	icns_type_str(maskType,maskStr);

	/* Only convert the icons that match sizes icns supports */
	if (iconType == ICNS_NULL_TYPE)
	{
		fprintf(stderr, "Unable to determine icon type: PNG file '%s' is %dx%d\n", pngname, width, height);
		free(buffer);

		return FALSE;
	}

	if (bpp != 32)
	{
		fprintf(stderr, "Bit depth %d unsupported in '%s'\n", bpp, pngname);
		free(buffer);

		return FALSE;
	}

	icns_set_print_errors(0);
	if (icns_get_element_from_family(*iconFamily, iconType, &iconElement) == ICNS_STATUS_OK)
	{
		icns_set_print_errors(1);

		fprintf(stderr, "Duplicate icon element of type '%s' detected (%s)\n", iconStr, pngname);
		free(buffer);

		return FALSE;
	}
	
	icns_set_print_errors(1);
	
	#if DEBUG_ICNSUTIL
	if(maskType != ICNS_NULL_TYPE)
	{
		printf("Using icns type '%s', mask '%s' for '%s'\n", iconStr, maskStr, pngname);
	}
	else
	{
		printf("Using icns type '%s' (ARGB) for '%s'\n", iconStr, pngname);
	}
	#endif
	
	icnsErr = icns_new_element_from_image(&icnsImage, iconType, &iconElement);
	
	if (iconElement != NULL)
	{
		if (icnsErr == ICNS_STATUS_OK)
		{
			icns_set_element_in_family(iconFamily, iconElement);
		}
		free(iconElement);
	}

	if(maskType != ICNS_NULL_TYPE)
	{
		icns_init_image_for_type(maskType, &icnsMask);

		iconDataOffset = 0;
		maskDataOffset = 0;
	
		while ((iconDataOffset < icnsImage.imageDataSize) && (maskDataOffset < icnsMask.imageDataSize))
		{
			icnsMask.imageData[maskDataOffset] = icnsImage.imageData[iconDataOffset+3];
			iconDataOffset += 4; /* move to the next alpha byte */
			maskDataOffset += 1; /* move to the next byte */
		}

		icnsErr = icns_new_element_from_mask(&icnsMask, maskType, &maskElement);

		if (maskElement != NULL)
		{
			if (icnsErr == ICNS_STATUS_OK)
			{
				icns_set_element_in_family(iconFamily, maskElement);
			}
			free(maskElement);
		}
		
		icns_free_image(&icnsMask);
	}

	free(buffer);

	return TRUE;
}
Example #2
0
ICNSSaver::ICNSSaver(BPositionIO *stream, uint32 rowBytes, icns_type_t type)
{
	fCreated = false;	

	icns_icon_info_t imageTypeInfo = icns_get_image_info_for_type(type);	
	int iconWidth = imageTypeInfo.iconWidth;
	int iconHeight = imageTypeInfo.iconWidth;
	int bpp = 32;

	uint8 *bits = new uint8[iconWidth * iconHeight * sizeof(uint32)];
	
	uint8 *rowPtr = bits;
	for (int i = 0; i < iconHeight; i++) {
		stream->Read(rowPtr, rowBytes);
		uint8 *bytePtr = rowPtr;
		for (int j=0; j < iconWidth; j++) {
			uint8 temp = bytePtr[0];
			bytePtr[0] = bytePtr[2];
			bytePtr[2] = temp;
			bytePtr += sizeof(uint32);
		}
		rowPtr += iconWidth * sizeof(uint32);
	}
	
	icns_create_family(&fIconFamily);
	
	icns_image_t icnsImage;	
	icnsImage.imageWidth = iconWidth;
	icnsImage.imageHeight = iconHeight;
	icnsImage.imageChannels = 4;
	icnsImage.imagePixelDepth = 8;
	icnsImage.imageDataSize = iconWidth * iconHeight * 4;
	icnsImage.imageData = bits;		

	icns_icon_info_t iconInfo;
	iconInfo.isImage = 1;
	iconInfo.iconWidth = icnsImage.imageWidth;
	iconInfo.iconHeight = icnsImage.imageHeight;
	iconInfo.iconBitDepth = bpp;
	iconInfo.iconChannels = (bpp == 32 ? 4 : 1);
	iconInfo.iconPixelDepth = bpp / iconInfo.iconChannels;

	icns_type_t iconType = icns_get_type_from_image_info(iconInfo);
	
	if (iconType == ICNS_NULL_TYPE) {
		delete bits;
		free(fIconFamily);
		fIconFamily = NULL;
		return;
	}

	icns_element_t *iconElement = NULL;
	int icnsErr = icns_new_element_from_image(&icnsImage, iconType,
		&iconElement);
		
	if (iconElement != NULL) {
		if (icnsErr == ICNS_STATUS_OK) {
			icns_set_element_in_family(&fIconFamily, iconElement);
			fCreated = true;
		}
		free(iconElement);
	}
	
	if (iconType != ICNS_1024x1024_32BIT_ARGB_DATA
		&& iconType != ICNS_512x512_32BIT_ARGB_DATA
		&& iconType != ICNS_256x256_32BIT_ARGB_DATA)
	{
		icns_type_t maskType = icns_get_mask_type_for_icon_type(iconType);
		
		icns_image_t icnsMask;
		icns_init_image_for_type(maskType, &icnsMask);

		uint32 iconDataOffset = 0;
		uint32 maskDataOffset = 0;
	
		while (iconDataOffset < icnsImage.imageDataSize 
			&& maskDataOffset < icnsMask.imageDataSize)	{
			icnsMask.imageData[maskDataOffset] =
				icnsImage.imageData[iconDataOffset + 3];
			iconDataOffset += 4;
			maskDataOffset += 1;
		}
		
		icns_element_t *maskElement = NULL;
		icnsErr = icns_new_element_from_mask(&icnsMask, maskType,
			&maskElement);

		if (maskElement != NULL) {
			if (icnsErr == ICNS_STATUS_OK)
				icns_set_element_in_family(&fIconFamily, maskElement);
			else
				fCreated = false;
			free(maskElement);
		}		
		icns_free_image(&icnsMask);
	}	
		
	if (!fCreated) {
		free(fIconFamily);
		fIconFamily = NULL;
	}
	
	delete bits;
}