int iconset_to_icns(char *srcfile, char *dstfile) { FILE *icnsfile; icns_family_t *iconFamily; char *pngfile = NULL; char *outfile = NULL; int srclen = strlen(srcfile); int i = 0; pngfile = malloc(srclen + 32); strncpy(&pngfile[0],&srcfile[0],srclen); pngfile[srclen] = '/'; if(dstfile == NULL) { int srcstart = srclen - 1; while(srcfile[srcstart] != '/' && srcfile[srcstart] != '.' && srcstart > 0) srcstart--; if(srcfile[srcstart] != '.' || srcstart == 0) srcstart = srclen; outfile = malloc(srclen + 6); strncpy(&outfile[0],&srcfile[0],srcstart); strncpy(&outfile[srcstart],".icns",6); dstfile = outfile; } icnsfile = fopen (dstfile, "wb+"); if (icnsfile == NULL) { fprintf (stderr, "Could not open '%s' for writing: %s\n", dstfile, strerror(errno)); goto cleanup; } icns_create_family(&iconFamily); while(iconset_names[i] != NULL) { strcpy(&pngfile[srclen],iconset_names[i]); #if DEBUG_ICNSUTIL printf("Adding %s\n",pngfile); #endif add_png_to_family(&iconFamily,pngfile); i++; } if (icns_write_family_to_file(icnsfile, iconFamily) != ICNS_STATUS_OK) { fprintf(stderr, "Failed to write icns file\n"); fclose(icnsfile); goto cleanup; } fclose(icnsfile); #if DEBUG_ICNSUTIL printf("Saved icns file to %s\n",dstfile); #endif cleanup: if(iconFamily != NULL) free(iconFamily); if(outfile != NULL) free(outfile); if(pngfile != NULL) free(pngfile); return 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; }