// --------------------------------------------------------------- // translate_from_bits_to_bits // // Convert the data in inSource from the Be Bitmap format ('bits') // to the format specified in outType (either bits or Base). // // Preconditions: // // Parameters: inSource, the bits data to translate // // amtread, the amount of data already read from // inSource // // read, pointer to the data already read from // inSource // // outType, the type of data to convert to // // outDestination, where the output is written to // // Postconditions: // // Returns: B_NO_TRANSLATOR, if the data is not in a supported // format // // B_ERROR, if there was an error allocating memory or some other // error // // B_OK, if successfully translated the data from the bits format // --------------------------------------------------------------- status_t BaseTranslator::translate_from_bits_to_bits(BPositionIO *inSource, uint32 outType, BPositionIO *outDestination) { TranslatorBitmap bitsHeader; bool bheaderonly = false, bdataonly = false; status_t result; result = identify_bits_header(inSource, NULL, &bitsHeader); if (result != B_OK) return result; // Translate B_TRANSLATOR_BITMAP to B_TRANSLATOR_BITMAP, easy enough :) if (outType == B_TRANSLATOR_BITMAP) { // write out bitsHeader (only if configured to) if (bheaderonly || (!bheaderonly && !bdataonly)) { if (swap_data(B_UINT32_TYPE, &bitsHeader, sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN) != B_OK) return B_ERROR; if (outDestination->Write(&bitsHeader, sizeof(TranslatorBitmap)) != sizeof(TranslatorBitmap)) return B_ERROR; } // write out the data (only if configured to) if (bdataonly || (!bheaderonly && !bdataonly)) { uint8 buf[1024]; uint32 remaining = B_BENDIAN_TO_HOST_INT32(bitsHeader.dataSize); ssize_t rd, writ; rd = inSource->Read(buf, 1024); while (rd > 0) { writ = outDestination->Write(buf, rd); if (writ < 0) break; remaining -= static_cast<uint32>(writ); rd = inSource->Read(buf, min(1024, remaining)); } if (remaining > 0) return B_ERROR; else return B_OK; } else return B_OK; } else return B_NO_TRANSLATOR; }
status_t BaseTranslator::BitsIdentify(BPositionIO *inSource, const translation_format *inFormat, BMessage *ioExtension, translator_info *outInfo, uint32 outType) { status_t result; result = BitsCheck(inSource, ioExtension, outType); if (result == B_OK) result = identify_bits_header(inSource, outInfo); else if (result == B_OK + 1) // if NOT B_TRANSLATOR_BITMAP, it could be an image in the // derived format result = DerivedIdentify(inSource, inFormat, ioExtension, outInfo, outType); return result; }
status_t BaseTranslator::BitsIdentify(BPositionIO *inSource, const translation_format *inFormat, BMessage *ioExtension, translator_info *outInfo, uint32 outType) { status_t result = BitsCheck(inSource, ioExtension, outType); if (result == B_OK) { TranslatorBitmap bitmap; result = identify_bits_header(inSource, outInfo, &bitmap); if (result == B_OK) result = DerivedCanHandleImageSize(bitmap.bounds.Width() + 1.0, bitmap.bounds.Height() + 1.0); } else if (result >= B_OK) { // if NOT B_TRANSLATOR_BITMAP, it could be an image in the // derived format result = DerivedIdentify(inSource, inFormat, ioExtension, outInfo, outType); } return result; }
status_t WebPTranslator::_TranslateFromBits(BPositionIO* stream, BMessage* ioExtension, uint32 outType, BPositionIO* target) { if (!outType) outType = WEBP_IMAGE_FORMAT; if (outType != WEBP_IMAGE_FORMAT) return B_NO_TRANSLATOR; TranslatorBitmap bitsHeader; status_t status; status = identify_bits_header(stream, NULL, &bitsHeader); if (status != B_OK) return status; if (bitsHeader.colors == B_CMAP8) { // TODO: support whatever colospace by intermediate colorspace conversion printf("Error! Colorspace not supported\n"); return B_NO_TRANSLATOR; } int32 bitsBytesPerPixel = 0; switch (bitsHeader.colors) { case B_RGB32: case B_RGB32_BIG: case B_RGBA32: case B_RGBA32_BIG: case B_CMY32: case B_CMYA32: case B_CMYK32: bitsBytesPerPixel = 4; break; case B_RGB24: case B_RGB24_BIG: case B_CMY24: bitsBytesPerPixel = 3; break; case B_RGB16: case B_RGB16_BIG: case B_RGBA15: case B_RGBA15_BIG: case B_RGB15: case B_RGB15_BIG: bitsBytesPerPixel = 2; break; case B_CMAP8: case B_GRAY8: bitsBytesPerPixel = 1; break; default: return B_ERROR; } if (bitsBytesPerPixel < 3) { // TODO support return B_NO_TRANSLATOR; } WebPPicture picture; WebPConfig config; if (!WebPPictureInit(&picture) || !WebPConfigInit(&config)) { printf("Error! Version mismatch!\n"); return B_ERROR; } WebPPreset preset = (WebPPreset)fSettings->SetGetInt32(WEBP_SETTING_PRESET); config.quality = (float)fSettings->SetGetInt32(WEBP_SETTING_QUALITY); if (!WebPConfigPreset(&config, (WebPPreset)preset, config.quality)) { printf("Error! Could initialize configuration with preset."); return B_ERROR; } config.method = fSettings->SetGetInt32(WEBP_SETTING_METHOD); config.preprocessing = fSettings->SetGetBool(WEBP_SETTING_PREPROCESSING); if (!WebPValidateConfig(&config)) { printf("Error! Invalid configuration.\n"); return B_ERROR; } picture.width = bitsHeader.bounds.IntegerWidth() + 1; picture.height = bitsHeader.bounds.IntegerHeight() + 1; int stride = bitsHeader.rowBytes; int bitsSize = picture.height * stride; uint8* bits = (uint8*)malloc(bitsSize); if (bits == NULL) return B_NO_MEMORY; if (stream->Read(bits, bitsSize) != bitsSize) { free(bits); return B_IO_ERROR; } if (!WebPPictureImportBGRA(&picture, bits, stride)) { printf("Error! WebPEncode() failed!\n"); free(bits); return B_ERROR; } free(bits); picture.writer = _EncodedWriter; picture.custom_ptr = target; picture.stats = NULL; if (!WebPEncode(&config, &picture)) { printf("Error! WebPEncode() failed!\n"); status = B_NO_TRANSLATOR; } else status = B_OK; WebPPictureFree(&picture); return status; }