libopenraw
|
00001 /* -*- tab-width:4; indent-tabs-mode:'t c-file-style:"stroustrup" -*- */ 00002 /* 00003 * libopenraw - unpack.cpp 00004 * 00005 * Copyright (C) 2008 Hubert Figuiere 00006 * Copyright (C) 2008 Novell, Inc. 00007 * 00008 * This library is free software: you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation, either version 3 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library. If not, see 00020 * <http://www.gnu.org/licenses/>. 00021 */ 00022 00023 00024 #include <assert.h> 00025 #include "unpack.h" 00026 #include "trace.h" 00027 #include "ifd.h" 00028 00029 namespace OpenRaw { namespace Internals { 00030 00031 using namespace Debug; 00032 00033 Unpack::Unpack(uint32_t w, uint32_t t) 00034 : m_w(w), m_type(t) 00035 { 00036 } 00037 00038 /* Return the size of an image row. */ 00039 size_t Unpack::block_size() 00040 { 00041 size_t bs; 00042 if(m_type == IFD::COMPRESS_NIKON_PACK) { 00043 bs = (m_w / 2 * 3) + (m_w / 10); 00044 } 00045 else { 00046 bs = m_w / 2 * 3; 00047 } 00048 return bs; 00049 } 00050 00051 00056 size_t Unpack::unpack_be12to16(uint8_t *dest, const uint8_t *src, 00057 size_t size) 00058 { 00059 uint16_t *dest16 = reinterpret_cast<uint16_t *>(dest); 00060 size_t pad = (m_type == IFD::COMPRESS_NIKON_PACK) ? 1 : 0; 00061 size_t n = size / (15 + pad); 00062 size_t rest = size % (15 + pad); 00063 size_t ret = n * 20 + rest / 3 * 4; 00064 00065 /* The inner loop advances 10 columns, which corresponds to 15 input 00066 bytes, 20 output bytes and, in a Nikon pack, one padding byte.*/ 00067 if (pad) { 00068 assert (size % 16 == 0); 00069 } 00070 assert (rest % 3 == 0); 00071 00072 for (size_t i = 0; i < n + 1; i++) { 00073 size_t m = i == n ? rest / 3 : 5; 00074 for(size_t j = 0; j < m; j++) { 00075 /* Read 3 bytes */ 00076 uint32_t t = *src++; 00077 t <<= 8; 00078 t |= *src++; 00079 t <<= 8; 00080 t |= *src++; 00081 00082 /* Write two 16 bit values. */ 00083 *dest16 = (t & (0xfff << 12)) >> 12; 00084 dest16++; 00085 00086 *dest16 = t & 0xfff; 00087 dest16++; 00088 } 00089 00090 src += pad; 00091 } 00092 00093 return ret; 00094 } 00095 00096 } }