unpack.cpp

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 "debug.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 } }

Generated by  doxygen 1.6.2