int ICNSLoader::GetIcon(BPositionIO *target, int index) { if (index < 1 || index > fIconsCount || !fLoaded) return B_NO_TRANSLATOR; icns_image_t iconImage; memset(&iconImage, 0, sizeof(icns_image_t)); icns_type_t typeItem = *((icns_type_t*)fFormatList.ItemAt(index - 1)); int status = icns_get_image32_with_mask_from_family(fIconFamily, typeItem, &iconImage); if (status != 0) return B_NO_TRANSLATOR; TranslatorBitmap bitsHeader; bitsHeader.magic = B_TRANSLATOR_BITMAP; bitsHeader.bounds.left = 0; bitsHeader.bounds.top = 0; bitsHeader.bounds.right = iconImage.imageWidth - 1; bitsHeader.bounds.bottom = iconImage.imageHeight - 1; bitsHeader.rowBytes = sizeof(uint32) * iconImage.imageWidth; bitsHeader.colors = B_RGBA32; bitsHeader.dataSize = bitsHeader.rowBytes * iconImage.imageHeight; if (swap_data(B_UINT32_TYPE, &bitsHeader, sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN) != B_OK) { icns_free_image(&iconImage); return B_NO_TRANSLATOR; } target->Write(&bitsHeader, sizeof(TranslatorBitmap)); uint8 *rowBuff = new uint8[iconImage.imageWidth * sizeof(uint32)]; for (uint32 i = 0; i < iconImage.imageHeight; i++) { uint8 *rowData = iconImage.imageData + (i * iconImage.imageWidth * sizeof(uint32)); uint8 *rowBuffPtr = rowBuff; for (uint32 j=0; j < iconImage.imageWidth; j++) { rowBuffPtr[0] = rowData[2]; rowBuffPtr[1] = rowData[1]; rowBuffPtr[2] = rowData[0]; rowBuffPtr[3] = rowData[3]; rowBuffPtr += sizeof(uint32); rowData += sizeof(uint32); } target->Write(rowBuff, iconImage.imageWidth * sizeof(uint32)); } delete rowBuff; icns_free_image(&iconImage); return B_OK; }
int icns_to_iconset(char *srcfile, char *dstpath) { FILE *inFile = NULL; char *outfile = NULL; int srclen = strlen(srcfile); icns_family_t *iconFamily = NULL; int dstpathlen = 0; int dstfilelen = 0; char *dstfile = NULL; icns_image_t iconImage; int i = 0; int error = 0; // Initialize the icon image memset ( &iconImage, 0, sizeof(icns_image_t) ); // If no dstpath given, create one based on the filename if(dstpath == NULL) { int srcstart = srclen - 1; while(srcfile[srcstart] != '/' && srcfile[srcstart] != '.' && srcstart > 0) srcstart--; if(srcfile[srcstart] != '.' || srcstart == 0) srcstart = srclen; outfile = malloc(srclen + 9); strncpy(&outfile[0],&srcfile[0],srcstart); strncpy(&outfile[srcstart],".iconset",9); dstpath = outfile; } // Prepare the dstfile variable for use dstpathlen = strlen(dstpath); dstfilelen = dstpathlen + 24; dstfile = malloc(dstfilelen); strncpy(&dstfile[0],&dstpath[0],dstpathlen); #if DEBUG_ICNSUTIL printf("Extracting images from %s\n",&srcfile[0]); #endif // Load the icns file inFile = fopen(srcfile, "r" ); if ( inFile == NULL ) { fprintf (stderr, "Unable to open file %s!\n",srcfile); goto cleanup; } error = icns_read_family_from_file(inFile,&iconFamily); fclose(inFile); // Create the .iconset directory if (mkdir(dstpath,0777) == -1) { if(errno == EEXIST) { errno = 0; } else { fprintf (stderr, "Error creating directory %s!\n",&dstpath[0]); error = 1; goto cleanup; } } // Loop through all the expected names/types and try to find + save while(iconset_names[i] != NULL) { int iconset_namelen = strlen(iconset_names[i]); char typeStr[5]; icns_type_str(iconset_types[i],typeStr); error = icns_get_image32_with_mask_from_family(iconFamily,iconset_types[i],&iconImage); if(error == ICNS_STATUS_OK) { strncpy(&dstfile[dstpathlen],iconset_names[i],iconset_namelen+1); FILE *outfile = fopen(&dstfile[0],"w"); if(!outfile) { fprintf (stderr, "Unable to open %s for writing!\n",&dstfile[0]); } else { error = write_png(outfile,&iconImage,NULL); if(error) { fprintf (stderr, "Error writing PNG image!\n"); } #if DEBUG_ICNSUTIL else { printf("Extracted %s\n",&dstfile[0]); } #endif if(outfile != NULL) { fclose(outfile); outfile = NULL; } } } icns_free_image(&iconImage); i++; } free(dstfile); cleanup: if(outfile) { free(outfile); outfile = NULL; } return error; }