From 4efb3cc0f44d5be5a63ac9391efe5326386b8533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 14 Feb 2005 15:09:46 +0000 Subject: [PATCH] Now also support reading in cursor images (.CUR files seem to have the same format as .ICO files). Now ignores the alpha channel mask if it couldn't be read completely instead of not being able to read the image at all. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11369 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/translators/icotranslator/ICO.cpp | 24 +++++++++++++++---- src/add-ons/translators/icotranslator/ICO.h | 9 +++++-- .../icotranslator/ICOTranslator.cpp | 6 +++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/add-ons/translators/icotranslator/ICO.cpp b/src/add-ons/translators/icotranslator/ICO.cpp index 2337750256..4cd9c5a2de 100644 --- a/src/add-ons/translators/icotranslator/ICO.cpp +++ b/src/add-ons/translators/icotranslator/ICO.cpp @@ -41,6 +41,15 @@ class TempAllocator { }; +bool +ico_header::IsValid() const +{ + return reserved == 0 + && (type == kTypeIcon || type == kTypeCursor) + && entry_count < 32; +} + + void ico_header::SwapToHost() { @@ -305,8 +314,11 @@ convert_data_to_bits(ico_dir_entry &entry, ico_bitmap_header &header, if (bitsPerPixel != 32) { bytesRead = source.Read(andData, andDataSize); - if (bytesRead != andDataSize) - return B_BAD_DATA; + if (bytesRead != andDataSize) { + // reading the alpha channel failed, so we're ignoring it + // (but we're still able to show the image data) + andData = NULL; + } } for (uint32 row = 0; row < entry.height; row++) { @@ -355,7 +367,8 @@ convert_data_to_bits(ico_dir_entry &entry, ico_bitmap_header &header, if (bitsPerPixel != 32) { // set alpha channel - if (get_1_bit_per_pixel(get_data_row(andData, andDataSize, andRowBytes, row), x)) + if (andData != NULL + && get_1_bit_per_pixel(get_data_row(andData, andDataSize, andRowBytes, row), x)) outRowData[x] = kMagicTransparentColor; else outRowData[x].alpha = 255; @@ -483,7 +496,7 @@ convert_bits_to_data(TranslatorBitmap &bitsHeader, uint8 *bitsData, ico_dir_entr status_t -ICO::identify(BMessage *settings, BPositionIO &stream, int32 &bitsPerPixel) +ICO::identify(BMessage *settings, BPositionIO &stream, uint8 &type, int32 &bitsPerPixel) { // read in the header @@ -499,6 +512,7 @@ ICO::identify(BMessage *settings, BPositionIO &stream, int32 &bitsPerPixel) return B_BAD_VALUE; int32 iconIndex = 0; + type = header.type; if (settings) { // Add page count to ioExtension @@ -515,6 +529,8 @@ ICO::identify(BMessage *settings, BPositionIO &stream, int32 &bitsPerPixel) return B_NO_TRANSLATOR; } + TRACE(("iconIndex = %ld, count = %ld\n", iconIndex, header.entry_count)); + // read in directory entries for (uint32 i = 0; i < header.entry_count; i++) { diff --git a/src/add-ons/translators/icotranslator/ICO.h b/src/add-ons/translators/icotranslator/ICO.h index c7f29bcb1f..1dec2d8c15 100644 --- a/src/add-ons/translators/icotranslator/ICO.h +++ b/src/add-ons/translators/icotranslator/ICO.h @@ -17,12 +17,17 @@ namespace ICO { // All ICO structures are written in little endian format +enum ico_type { + kTypeIcon = 1, + kTypeCursor = 2, +}; + struct ico_header { uint16 reserved; uint16 type; uint16 entry_count; - bool IsValid() const { return reserved == 0 && type == 1 && entry_count < 32; } + bool IsValid() const; void SwapToHost(); void SwapFromHost(); } _PACKED; @@ -79,7 +84,7 @@ struct rgba32_color { }; -extern status_t identify(BMessage *settings, BPositionIO &stream, int32 &bitsPerPixel); +extern status_t identify(BMessage *settings, BPositionIO &stream, uint8 &type, int32 &bitsPerPixel); extern status_t convert_ico_to_bits(BMessage *settings, BPositionIO &source, BPositionIO &target); extern status_t convert_bits_to_ico(BMessage *settings, BPositionIO &source, TranslatorBitmap &bitsHeader, BPositionIO &target); diff --git a/src/add-ons/translators/icotranslator/ICOTranslator.cpp b/src/add-ons/translators/icotranslator/ICOTranslator.cpp index d6d4f3db9e..6713387c75 100644 --- a/src/add-ons/translators/icotranslator/ICOTranslator.cpp +++ b/src/add-ons/translators/icotranslator/ICOTranslator.cpp @@ -99,14 +99,16 @@ ICOTranslator::DerivedIdentify(BPositionIO *stream, return B_NO_TRANSLATOR; int32 bitsPerPixel; - if (ICO::identify(ioExtension, *stream, bitsPerPixel) != B_OK) + uint8 type; + if (ICO::identify(ioExtension, *stream, type, bitsPerPixel) != B_OK) return B_NO_TRANSLATOR; info->type = ICO_IMAGE_FORMAT; info->group = B_TRANSLATOR_BITMAP; info->quality = ICO_IN_QUALITY; info->capability = ICO_IN_CAPABILITY; - snprintf(info->name, sizeof(info->name), "Windows Icon %ld bit image", bitsPerPixel); + snprintf(info->name, sizeof(info->name), "Windows %s %ld bit image", + type == ICO::kTypeIcon ? "Icon" : "Cursor", bitsPerPixel); strcpy(info->MIME, kICOMimeType); return B_OK;