Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:lafenghu
libopenraw
libopenraw-orf-thumbnail.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libopenraw-orf-thumbnail.patch of Package libopenraw
From 9be26e10ecbf89ce99b294906be1208d5a484c7e Mon Sep 17 00:00:00 2001 From: Hubert Figuiere <hub@figuiere.net> Date: Fri, 18 Mar 2011 23:41:38 -0700 Subject: [PATCH 1/2] Better support for compression ID Implement Olympus decompression (with decompressor borrowed from RawSpeed) --- AUTHORS | 3 + lib/Makefile.am | 2 + lib/bititerator.cpp | 30 +++++-- lib/bititerator.h | 4 +- lib/dngfile.cpp | 2 +- lib/ifd.h | 4 +- lib/ifdfile.cpp | 14 +++- lib/ifdfile.h | 7 ++ lib/olympusdecompressor.cpp | 205 +++++++++++++++++++++++++++++++++++++++++++ lib/olympusdecompressor.h | 51 +++++++++++ lib/orffile.cpp | 28 +++++- lib/orffile.h | 5 + lib/peffile.cpp | 2 +- 13 files changed, 338 insertions(+), 19 deletions(-) create mode 100644 lib/olympusdecompressor.cpp create mode 100644 lib/olympusdecompressor.h Index: libopenraw-0.0.8/AUTHORS =================================================================== --- libopenraw-0.0.8.orig/AUTHORS +++ libopenraw-0.0.8/AUTHORS @@ -4,6 +4,9 @@ MRW support: Bradley Broom NEF decompression: Rafael EspĂndola Python bindings: Brian Quinlan +Indirect contributors: +Klaus Post for code from RawSpeed. + Sponsors: Novell sponsored time to work on libopenraw as part of their ITO programme (and HackWeek in February 2008) Index: libopenraw-0.0.8/lib/Makefile.am =================================================================== --- libopenraw-0.0.8.orig/lib/Makefile.am +++ libopenraw-0.0.8/lib/Makefile.am @@ -32,6 +32,7 @@ noinst_HEADERS = or_debug.h \ ljpegdecompressor.h \ ljpegdecompressor_priv.h \ crwdecompressor.h \ + olympusdecompressor.h \ exception.h \ endianutils.h \ metavalue.h \ @@ -83,6 +84,7 @@ libopenraw_la_SOURCES = \ decompressor.cpp \ ljpegdecompressor.cpp \ crwdecompressor.cpp \ + olympusdecompressor.cpp \ metavalue.cpp \ unpack.cpp \ bimedian_demosaic.cpp demosaic.h \ Index: libopenraw-0.0.8/lib/bititerator.cpp =================================================================== --- libopenraw-0.0.8.orig/lib/bititerator.cpp +++ libopenraw-0.0.8/lib/bititerator.cpp @@ -20,6 +20,7 @@ */ #include <assert.h> +#include <algorithm> #include "bititerator.h" namespace OpenRaw { @@ -53,22 +54,35 @@ void BitIterator::load(size_t numBits) uint32_t BitIterator::get(size_t n) { - assert(n <= 25); + uint32_t ret = peek(n); + + skip(n); + return ret; +} + +uint32_t BitIterator::peek(size_t n) +{ + assert(n <= 25); + if (n == 0) return 0; - + if (n > m_bitsOnBuffer) load(n - m_bitsOnBuffer); - + assert(n <= m_bitsOnBuffer); + + return m_bitBuffer >> (32 - n); +} - uint32_t ret = m_bitBuffer >> (32 - n); - m_bitsOnBuffer -= n; - m_bitBuffer <<= n; - - return ret; +void BitIterator::skip(size_t n) +{ + size_t num_bits = std::min(n, m_bitsOnBuffer); + m_bitsOnBuffer -= num_bits; + m_bitBuffer <<= num_bits; } + } } Index: libopenraw-0.0.8/lib/bititerator.h =================================================================== --- libopenraw-0.0.8.orig/lib/bititerator.h +++ libopenraw-0.0.8/lib/bititerator.h @@ -31,12 +31,14 @@ namespace Internals { class BitIterator { const uint8_t* m_p; uint32_t m_bitBuffer; - uint8_t m_bitsOnBuffer; + size_t m_bitsOnBuffer; void load(size_t numBits); public: BitIterator(const void *); uint32_t get(size_t); + uint32_t peek(size_t); + void skip(size_t); }; } Index: libopenraw-0.0.8/lib/dngfile.cpp =================================================================== --- libopenraw-0.0.8.orig/lib/dngfile.cpp +++ libopenraw-0.0.8/lib/dngfile.cpp @@ -89,7 +89,7 @@ namespace OpenRaw { if(ret == OR_ERROR_NONE) { uint16_t compression = 0; if (m_cfaIfd->getValue(IFD::EXIF_TAG_COMPRESSION, compression) && - compression == 7) { + compression == IFD::COMPRESS_LJPEG) { // if the option is not set, decompress if ((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) { boost::scoped_ptr<IO::Stream> s(new IO::MemStream(data.data(), Index: libopenraw-0.0.8/lib/ifd.h =================================================================== --- libopenraw-0.0.8.orig/lib/ifd.h +++ libopenraw-0.0.8/lib/ifd.h @@ -69,8 +69,10 @@ namespace OpenRaw { typedef enum { COMPRESS_NONE = 1, COMPRESS_JPEG = 6, + COMPRESS_LJPEG = 7, /**< Lossless JPEG, see DNG */ COMPRESS_NIKON_PACK = 32769, - COMPRESS_NIKON_QUANTIZED = 34713 + COMPRESS_NIKON_QUANTIZED = 34713, + COMPRESS_CUSTOM = 65535 /**< The value everybody seems to use */ } TiffCompress; } } Index: libopenraw-0.0.8/lib/ifdfile.cpp =================================================================== --- libopenraw-0.0.8.orig/lib/ifdfile.cpp +++ libopenraw-0.0.8/lib/ifdfile.cpp @@ -339,6 +339,15 @@ MetaValue *IFDFile::_getMetaValue(int32_ } return val; } + +/** by default we don't translate the compression + */ +uint32_t IFDFile::_translateCompressionType(IFD::TiffCompress tiffCompression) +{ + return (uint32_t)tiffCompression; +} + + namespace { @@ -541,14 +550,15 @@ static RawData::CfaPattern _getCfaPatter return OR_ERROR_NOT_FOUND; } - uint32_t compression = 0; - got_it = dir->getIntegerValue(IFD::EXIF_TAG_COMPRESSION, compression); + uint16_t tiffCompression = 0; + got_it = dir->getValue(IFD::EXIF_TAG_COMPRESSION, tiffCompression); if(!got_it) { Trace(DEBUG1) << "Compression type not found\n"; } BitmapData::DataType data_type = OR_DATA_TYPE_NONE; + uint32_t compression = _translateCompressionType((IFD::TiffCompress)tiffCompression); switch(compression) { case IFD::COMPRESS_NONE: Index: libopenraw-0.0.8/lib/ifdfile.h =================================================================== --- libopenraw-0.0.8.orig/lib/ifdfile.h +++ libopenraw-0.0.8/lib/ifdfile.h @@ -102,6 +102,13 @@ namespace OpenRaw { virtual MetaValue *_getMetaValue(int32_t meta_index); + /** Translate the compression type from the tiff type (16MSB) + * to the RAW specific type if needed (16MSB) + * @param tiffCompression the 16 bits value from TIFF + * @return the actually value. Anything >= 2^16 is specific the RAW type + */ + virtual uint32_t _translateCompressionType(IFD::TiffCompress tiffCompression); + IFDDir::Ref m_cfaIfd; /**< the IFD for the CFA */ IFDDir::Ref m_mainIfd; /**< the IFD for the main image * does not necessarily reference Index: libopenraw-0.0.8/lib/olympusdecompressor.cpp =================================================================== --- /dev/null +++ libopenraw-0.0.8/lib/olympusdecompressor.cpp @@ -0,0 +1,207 @@ +/* + * libopenraw - olympusdecompressor.cpp + * + * Copyright (C) 2011 Hubert Figuiere + * Olympus Decompression copied from RawSpeed + * Copyright (C) 2009 Klaus Post + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> + +#include <libopenraw++/rawdata.h> + +#include "io/stream.h" +#include "olympusdecompressor.h" +#include "bititerator.h" + + +namespace OpenRaw { +namespace Internals { + +static void decompressOlympus(const uint8_t* buffer, uint8_t* data, uint32_t w, uint32_t h); + +// decompression ported from RawSpeed. +static void decompressOlympus(const uint8_t* buffer, uint8_t* data, uint32_t w, uint32_t h) +{ + int nbits, sign, low, high, i, wo0, n, nw0, wo1, nw1; + int acarry0[3], acarry1[3], pred, diff; + + int pitch = w * 2; //(((w * 2/*bpp*/) + 15) / 16) * 16; // TODO make that part of the outer datas + + /* Build a table to quickly look up "high" value */ + char bittable[4096]; + for (i = 0; i < 4096; i++) { + int b = i; + for (high = 0; high < 12; high++) { + if ((b>>(11-high))&1) { + break; + } + } + bittable[i] = high; + } + wo0 = nw0 = wo1 = nw1 = 0; + buffer += 7; + + BitIterator bits(buffer); + + for (uint32_t y = 0; y < h; y++) { + memset(acarry0, 0, sizeof acarry0); + memset(acarry1, 0, sizeof acarry1); + uint16_t* dest = (uint16_t*) & data[y*pitch]; + for (uint32_t x = 0; x < w; x++) { +// bits.checkPos(); +// bits.fill(); + i = 2 * (acarry0[2] < 3); + for (nbits = 2 + i; (uint16_t) acarry0[0] >> (nbits + i); nbits++) { + + } + + uint32_t b = bits.peek(15); + sign = (b >> 14) * -1; + low = (b >> 12) & 3; + high = bittable[b&4095]; + // Skip bits used above. + bits.skip(std::min(12+3, high + 1 + 3)); + + if (high == 12) { + high = bits.get(16 - nbits) >> 1; + } + + acarry0[0] = (high << nbits) | bits.get(nbits); + diff = (acarry0[0] ^ sign) + acarry0[1]; + acarry0[1] = (diff * 3 + acarry0[1]) >> 5; + acarry0[2] = acarry0[0] > 16 ? 0 : acarry0[2] + 1; + + if (y < 2 || x < 2) { + if (y < 2 && x < 2) { + pred = 0; + } + else if (y < 2) { + pred = wo0; + } + else { + pred = dest[-pitch+((int)x)]; + nw0 = pred; + } + dest[x] = pred + ((diff << 2) | low); + // Set predictor + wo0 = dest[x]; + } + else { + n = dest[-pitch+((int)x)]; + if (((wo0 < nw0) & (nw0 < n)) | ((n < nw0) & (nw0 < wo0))) { + if (abs(wo0 - nw0) > 32 || abs(n - nw0) > 32) { + pred = wo0 + n - nw0; + } + else { + pred = (wo0 + n) >> 1; + } + } + else { + pred = abs(wo0 - nw0) > abs(n - nw0) ? wo0 : n; + } + + dest[x] = pred + ((diff << 2) | low); + // Set predictors + wo0 = dest[x]; + nw0 = n; + } + // _ASSERTE(0 == dest[x] >> 12) ; + + // ODD PIXELS + x += 1; +// bits.checkPos(); +// bits.fill(); + i = 2 * (acarry1[2] < 3); + for (nbits = 2 + i; (uint16_t) acarry1[0] >> (nbits + i); nbits++) { + + } + b = bits.peek(15); + sign = (b >> 14) * -1; + low = (b >> 12) & 3; + high = bittable[b&4095]; + // Skip bits used above. + bits.skip(std::min(12+3, high + 1 + 3)); + + if (high == 12) { + high = bits.get(16 - nbits) >> 1; + } + + acarry1[0] = (high << nbits) | bits.get(nbits); + diff = (acarry1[0] ^ sign) + acarry1[1]; + acarry1[1] = (diff * 3 + acarry1[1]) >> 5; + acarry1[2] = acarry1[0] > 16 ? 0 : acarry1[2] + 1; + + if (y < 2 || x < 2) { + if (y < 2 && x < 2) { + pred = 0; + } + else if (y < 2) { + pred = wo1; + } + else { + pred = dest[-pitch+((int)x)]; + nw1 = pred; + } + dest[x] = pred + ((diff << 2) | low); + // Set predictor + wo1 = dest[x]; + } + else { + n = dest[-pitch+((int)x)]; + if (((wo1 < nw1) & (nw1 < n)) | ((n < nw1) & (nw1 < wo1))) { + if (abs(wo1 - nw1) > 32 || abs(n - nw1) > 32) { + pred = wo1 + n - nw1; + } + else { + pred = (wo1 + n) >> 1; + } + } + else { + pred = abs(wo1 - nw1) > abs(n - nw1) ? wo1 : n; + } + + dest[x] = pred + ((diff << 2) | low); + + // Set predictors + wo1 = dest[x]; + nw1 = n; + } + // _ASSERTE(0 == dest[x] >> 12) ; + } + } +} + +RawData *OlympusDecompressor::decompress(RawData *in) +{ + RawData *output; + if(in) { + output = in; + } + else { + output = new RawData; + } + + output->allocData(m_w * m_h * 2); + decompressOlympus(m_buffer, (uint8_t*)output->data(), m_w, m_h); + + return output; +} + + +} +} Index: libopenraw-0.0.8/lib/olympusdecompressor.h =================================================================== --- /dev/null +++ libopenraw-0.0.8/lib/olympusdecompressor.h @@ -0,0 +1,51 @@ +/* + * libopenraw - olympusdecompressor.cpp + * + * Copyright (C) 2011 Hubert Figuiere + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + + +#ifndef __OPENRAW_OLYMPUSDECOMPRESSOR_H__ +#define __OPENRAW_OLYMPUSDECOMPRESSOR_H__ + +#include "decompressor.h" + +namespace OpenRaw { +namespace Internals { + +class OlympusDecompressor + : public Decompressor +{ +public: + OlympusDecompressor(const uint8_t *buffer, + RawContainer * container, uint32_t w, uint32_t h) + : Decompressor(NULL, container) + , m_buffer(buffer) + , m_h(h) + , m_w(w) + { + } + virtual RawData *decompress(RawData *in = NULL); +private: + const uint8_t *m_buffer; + uint32_t m_h; + uint32_t m_w; +}; + +} +} +#endif Index: libopenraw-0.0.8/lib/orffile.cpp =================================================================== --- libopenraw-0.0.8.orig/lib/orffile.cpp +++ libopenraw-0.0.8/lib/orffile.cpp @@ -27,6 +27,7 @@ #include "ifddir.h" #include "ifdentry.h" #include "orfcontainer.h" +#include "olympusdecompressor.h" #include "io/file.h" using namespace Debug; @@ -103,19 +104,27 @@ namespace OpenRaw { // ORF files seems to be marked as uncompressed even if they are. uint32_t x = data.x(); uint32_t y = data.y(); - uint16_t compression = 0; + uint32_t compression = 0; if(data.size() < x * y * 2) { - compression = 65535; - data.setCompression(65535); + compression = ORF_COMPRESSION; + data.setCompression(ORF_COMPRESSION); data.setDataType(OR_DATA_TYPE_COMPRESSED_CFA); } else { compression = data.compression(); } switch(compression) { - case 65535: + case ORF_COMPRESSION: if((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) { - // TODO decompress + OlympusDecompressor decomp((const uint8_t*)data.data(), m_container, x, y); + RawData *dData = decomp.decompress(NULL); + if (dData != NULL) { + dData->setCfaPattern(data.cfaPattern()); + data.swap(*dData); + data.setDataType(OR_DATA_TYPE_CFA); + data.setDimensions(x, y); + delete dData; + } } break; default: @@ -124,6 +133,15 @@ namespace OpenRaw { } return err; } + +uint32_t OrfFile::_translateCompressionType(IFD::TiffCompress tiffCompression) +{ + if(tiffCompression == IFD::COMPRESS_CUSTOM) { + return ORF_COMPRESSION; + } + return (uint32_t)tiffCompression; +} + } } Index: libopenraw-0.0.8/lib/orffile.h =================================================================== --- libopenraw-0.0.8.orig/lib/orffile.h +++ libopenraw-0.0.8/lib/orffile.h @@ -43,11 +43,16 @@ namespace OpenRaw { OrfFile(IO::Stream *); virtual ~OrfFile(); + enum { + ORF_COMPRESSION = 0x10000 + }; + protected: virtual IFDDir::Ref _locateCfaIfd(); virtual IFDDir::Ref _locateMainIfd(); virtual ::or_error _getRawData(RawData & data, uint32_t options); + virtual uint32_t _translateCompressionType(IFD::TiffCompress tiffCompression); private: static RawFile::TypeId _typeIdFromModel(const std::string & model); Index: libopenraw-0.0.8/lib/peffile.cpp =================================================================== --- libopenraw-0.0.8.orig/lib/peffile.cpp +++ libopenraw-0.0.8/lib/peffile.cpp @@ -95,7 +95,7 @@ namespace OpenRaw { if(err == OR_ERROR_NONE) { uint16_t compression = data.compression(); switch(compression) { - case 65535: + case IFD::COMPRESS_CUSTOM: if((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) { // TODO decompress }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor