libopenraw
unpack.cpp
1/*
2 * libopenraw - unpack.cpp
3 *
4 * Copyright (C) 2008-2016 Hubert Figuiere
5 * Copyright (C) 2008 Novell, Inc.
6 *
7 * This library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22#include <assert.h>
23
24#include <libopenraw/consts.h>
25
26#include "unpack.hpp"
27#include "trace.hpp"
28#include "ifd.hpp"
29
30namespace OpenRaw {
31namespace Internals {
32
33using namespace Debug;
34
35Unpack::Unpack(uint32_t w, uint32_t t)
36 : m_w(w), m_type(t)
37{
38}
39
40/* Return the size of an image row. */
41size_t Unpack::block_size()
42{
43 size_t bs;
44 if(m_type == IFD::COMPRESS_NIKON_PACK) {
45 bs = (m_w / 2 * 3) + (m_w / 10);
46 }
47 else {
48 bs = m_w / 2 * 3;
49 }
50 return bs;
51}
52
53
58or_error Unpack::unpack_be12to16(uint8_t *dest, size_t destsize, const uint8_t *src,
59 size_t size, size_t & out)
60{
61 or_error err = OR_ERROR_NONE;
62 uint16_t *dest16 = reinterpret_cast<uint16_t *>(dest);
63 size_t pad = (m_type == IFD::COMPRESS_NIKON_PACK) ? 1 : 0;
64 size_t n = size / (15 + pad);
65 size_t rest = size % (15 + pad);
66 size_t ret = n * 20 + rest / 3 * 4;
67
68 out = 0;
69
70 /* The inner loop advances 10 columns, which corresponds to 15 input
71 bytes, 20 output bytes and, in a Nikon pack, one padding byte.*/
72 if (pad) {
73 if ((size % 16) != 0) {
74 LOGERR("be12to16 incorrect padding.\n");
75 return OR_ERROR_DECOMPRESSION;
76 }
77 }
78 if ((rest % 3) != 0) {
79 LOGERR("be12to16 incorrect rest.\n");
80 return OR_ERROR_DECOMPRESSION;
81 }
82
83 for (size_t i = 0; i < n + 1; i++) {
84 size_t m = (i == n) ? rest / 3 : 5;
85 if((reinterpret_cast<uint8_t *>(dest16) - dest) + (m * 4) > destsize) {
86 err = OR_ERROR_DECOMPRESSION;
87 LOGERR("overflow !\n");
88 break;
89 }
90 for(size_t j = 0; j < m; j++) {
91 /* Read 3 bytes */
92 uint32_t t = *src++;
93 t <<= 8;
94 t |= *src++;
95 t <<= 8;
96 t |= *src++;
97
98 /* Write two 16 bit values. */
99 *dest16 = (t & (0xfff << 12)) >> 12;
100 dest16++;
101
102 *dest16 = t & 0xfff;
103 dest16++;
104 }
105
106 src += pad;
107 }
108
109 out = ret;
110 return err;
111}
112
113} }
114/*
115 Local Variables:
116 mode:c++
117 c-file-style:"stroustrup"
118 c-file-offsets:((innamespace . 0))
119 tab-width:2
120 c-basic-offset:2
121 indent-tabs-mode:nil
122 fill-column:80
123 End:
124*/
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30