00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "unpack.h"
00024 #include "debug.h"
00025 #include "ifd.h"
00026
00027 namespace OpenRaw { namespace Internals {
00028
00029 using namespace Debug;
00030
00031 Unpack::Unpack(uint32_t w, uint32_t h, uint32_t t)
00032 : m_w(w), m_h(h),
00033 m_col(0), m_row(0),
00034 m_type(t)
00035 {
00036 }
00037
00038 size_t Unpack::block_size()
00039 {
00040 size_t bs;
00041 if(m_type == IFD::COMPRESS_NIKON_PACK) {
00042 bs = (m_w / 2 * 3) + (m_w / 10);
00043 }
00044 else {
00045 bs = m_w / 2 * 3;
00046 }
00047 return bs;
00048 }
00049
00050
00051 size_t Unpack::row_advance()
00052 {
00053 size_t skip_input = 0;
00054 if((m_type == IFD::COMPRESS_NIKON_PACK) && ((m_col % 10) == 9)) {
00055
00056 skip_input = 1;
00057 }
00058 m_col++;
00059 if(m_col == m_w) {
00060 m_col = 0;
00061 m_row++;
00062 }
00063 return skip_input;
00064 }
00065
00066
00070 size_t Unpack::unpack_be12to16(uint8_t *dest, size_t outsize,
00071 const uint8_t *src, size_t insize)
00072 {
00073 size_t skip;
00074 size_t inleft = insize;
00075 size_t outleft = outsize;
00076 uint16_t short_dest;
00077 if(inleft<= 0) {
00078 return 0;
00079 }
00080 do {
00081 if(inleft && outleft) {
00082 short_dest = ((*src & 0xf0) >> 4) << 8;
00083 outleft--;
00084 if(outleft) {
00085 short_dest |= (*src & 0x0f) << 4;
00086 inleft--; src++;
00087 }
00088 }
00089 if(inleft && outleft) {
00090 short_dest |= (*src & 0xf0) >> 4;
00091 *(uint16_t*)dest = short_dest;
00092 outleft--; dest+=2;
00093 skip = row_advance();
00094 if(skip) {
00095 src += skip;
00096 inleft -= skip;
00097 }
00098 }
00099 if(inleft && outleft) {
00100 short_dest = (*src & 0x0f) << 8;
00101 inleft--; src++;
00102 outleft--;
00103 }
00104 if(inleft && outleft) {
00105 short_dest |= *src;
00106 *(uint16_t*)dest = short_dest;
00107 inleft--; src++;
00108 outleft--; dest+=2;
00109 skip = row_advance();
00110 if(skip) {
00111 src += skip;
00112 inleft -= skip;
00113 }
00114 }
00115 } while(inleft && outleft);
00116 if(inleft) {
00117 Trace(WARNING) << "Left " << inleft << " bytes at the end.\n";
00118 }
00119 return outsize - outleft;
00120 }
00121
00122 } }