panasonic decoders: cleanup
This commit is contained in:
@@ -1,7 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RawTherapee.
|
||||||
|
*
|
||||||
|
* RawTherapee is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RawTherapee 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "StopWatch.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "dcraw.h"
|
#include "dcraw.h"
|
||||||
|
|
||||||
// Code adapted from libraw
|
// Code adapted from libraw
|
||||||
/* -*- C++ -*-
|
/* -*- C++ -*-
|
||||||
* Copyright 2019 LibRaw LLC (info@libraw.org)
|
* Copyright 2019 LibRaw LLC (info@libraw.org)
|
||||||
@@ -17,7 +33,6 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes)
|
unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes)
|
||||||
{
|
{
|
||||||
int byte;
|
int byte;
|
||||||
@@ -47,13 +62,16 @@ class pana_cs6_page_decoder
|
|||||||
{
|
{
|
||||||
unsigned int pixelbuffer[14], lastoffset, maxoffset;
|
unsigned int pixelbuffer[14], lastoffset, maxoffset;
|
||||||
unsigned char current, *buffer;
|
unsigned char current, *buffer;
|
||||||
public:
|
public:
|
||||||
pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize)
|
pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize)
|
||||||
: lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer)
|
: lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void read_page(); // will throw IO error if not enough space in buffer
|
void read_page(); // will throw IO error if not enough space in buffer
|
||||||
unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; }
|
unsigned int nextpixel()
|
||||||
|
{
|
||||||
|
return current < 14 ? pixelbuffer[current++] : 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i])
|
#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i])
|
||||||
@@ -83,18 +101,15 @@ void pana_cs6_page_decoder::read_page()
|
|||||||
|
|
||||||
void DCraw::panasonic_load_raw()
|
void DCraw::panasonic_load_raw()
|
||||||
{
|
{
|
||||||
StopWatch Stop1("panasonic_load_raw");
|
|
||||||
pana_bits_t pana_bits(ifp,load_flags, RT_pana_info.encoding);
|
|
||||||
int row, col, i, j, sh=0, pred[2], nonz[2];
|
|
||||||
unsigned bytes[16] = {};
|
|
||||||
|
|
||||||
pana_bits(0, 0);
|
|
||||||
int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9;
|
int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9;
|
||||||
if (RT_pana_info.encoding == 5) {
|
if (RT_pana_info.encoding == 5) {
|
||||||
for (row = 0; row < raw_height; row++) {
|
pana_bits_t pana_bits(ifp, load_flags, RT_pana_info.encoding);
|
||||||
|
pana_bits(0, 0);
|
||||||
|
unsigned bytes[16] = {};
|
||||||
|
for (int row = 0; row < raw_height; ++row) {
|
||||||
ushort* raw_block_data = raw_image + row * raw_width;
|
ushort* raw_block_data = raw_image + row * raw_width;
|
||||||
|
|
||||||
for (col = 0; col < raw_width; col += enc_blck_size) {
|
for (int col = 0; col < raw_width; col += enc_blck_size) {
|
||||||
pana_bits(0, bytes);
|
pana_bits(0, bytes);
|
||||||
|
|
||||||
if (RT_pana_info.bpp == 12) {
|
if (RT_pana_info.bpp == 12) {
|
||||||
@@ -111,10 +126,8 @@ StopWatch Stop1("panasonic_load_raw");
|
|||||||
}
|
}
|
||||||
else if (RT_pana_info.bpp == 14) {
|
else if (RT_pana_info.bpp == 14) {
|
||||||
raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8);
|
raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8);
|
||||||
raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) +
|
raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10);
|
||||||
((bytes[3] & 0xF) << 10);
|
raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12);
|
||||||
raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) +
|
|
||||||
((bytes[5] & 3) << 12);
|
|
||||||
raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6);
|
raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6);
|
||||||
raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8);
|
raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8);
|
||||||
raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10);
|
raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10);
|
||||||
@@ -129,83 +142,86 @@ StopWatch Stop1("panasonic_load_raw");
|
|||||||
} else if (RT_pana_info.encoding == 7) {
|
} else if (RT_pana_info.encoding == 7) {
|
||||||
panasonicC7_load_raw();
|
panasonicC7_load_raw();
|
||||||
} else {
|
} else {
|
||||||
for (row=0; row < height; row++)
|
pana_bits_t pana_bits(ifp, load_flags, RT_pana_info.encoding);
|
||||||
for (col=0; col < raw_width; col++) {
|
pana_bits(0, 0);
|
||||||
if ((i = col % 14) == 0)
|
int sh = 0, pred[2], nonz[2];
|
||||||
|
for (int row = 0; row < height; ++row) {
|
||||||
|
for (int col = 0; col < raw_width; ++col) {
|
||||||
|
int i;
|
||||||
|
if ((i = col % 14) == 0) {
|
||||||
pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
|
pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
|
||||||
if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
|
}
|
||||||
|
if (i % 3 == 2) {
|
||||||
|
sh = 4 >> (3 - pana_bits(2));
|
||||||
|
}
|
||||||
if (nonz[i & 1]) {
|
if (nonz[i & 1]) {
|
||||||
|
int j;
|
||||||
if ((j = pana_bits(8))) {
|
if ((j = pana_bits(8))) {
|
||||||
if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
|
if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) {
|
||||||
pred[i & 1] &= ~(-1 << sh);
|
pred[i & 1] &= ~(-1 << sh);
|
||||||
|
}
|
||||||
pred[i & 1] += j << sh;
|
pred[i & 1] += j << sh;
|
||||||
}
|
}
|
||||||
} else if ((nonz[i & 1] = pana_bits(8)) || i > 11)
|
} else if ((nonz[i & 1] = pana_bits(8)) || i > 11) {
|
||||||
pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
|
pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4);
|
||||||
if ((raw_image[(row)*raw_width+(col)] = pred[col & 1]) > 4098 && col < width) derror();
|
}
|
||||||
|
if ((raw_image[(row)*raw_width+(col)] = pred[col & 1]) > 4098 && col < width) {
|
||||||
|
derror();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCraw::panasonicC6_load_raw()
|
void DCraw::panasonicC6_load_raw()
|
||||||
{
|
{
|
||||||
const int rowstep = 16;
|
constexpr int rowstep = 16;
|
||||||
const int blocksperrow = raw_width / 11;
|
const int blocksperrow = raw_width / 11;
|
||||||
const int rowbytes = blocksperrow * 16;
|
const int rowbytes = blocksperrow * 16;
|
||||||
unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep);
|
unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep);
|
||||||
merror(iobuf, "panasonicC6_load_raw()");
|
merror(iobuf, "panasonicC6_load_raw()");
|
||||||
|
|
||||||
for (int row = 0; row < raw_height - rowstep + 1;
|
for (int row = 0; row < raw_height - rowstep + 1; row += rowstep) {
|
||||||
row += rowstep)
|
const int rowstoread = MIN(rowstep, raw_height - row);
|
||||||
{
|
fread(iobuf, rowbytes, rowstoread, ifp);
|
||||||
int rowstoread = MIN(rowstep, raw_height - row);
|
|
||||||
fread (iobuf, rowbytes, rowstoread, ifp);
|
|
||||||
// if (libraw_internal_data.internal_data.input->read(
|
|
||||||
// iobuf, rowbytes, rowstoread) != rowstoread)
|
|
||||||
// throw LIBRAW_EXCEPTION_IO_EOF;
|
|
||||||
pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread);
|
pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread);
|
||||||
for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0)
|
for (int crow = 0, col = 0; crow < rowstoread; ++crow, col = 0) {
|
||||||
{
|
|
||||||
unsigned short *rowptr = &raw_image[(row + crow) * raw_width];
|
unsigned short *rowptr = &raw_image[(row + crow) * raw_width];
|
||||||
for (int rblock = 0; rblock < blocksperrow; rblock++)
|
for (int rblock = 0; rblock < blocksperrow; rblock++) {
|
||||||
{
|
|
||||||
page.read_page();
|
page.read_page();
|
||||||
unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0};
|
unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0};
|
||||||
unsigned pmul = 0, pixel_base = 0;
|
unsigned pmul = 0, pixel_base = 0;
|
||||||
for (int pix = 0; pix < 11; pix++)
|
for (int pix = 0; pix < 11; ++pix) {
|
||||||
{
|
if (pix % 3 == 2) {
|
||||||
if (pix % 3 == 2)
|
|
||||||
{
|
|
||||||
unsigned base = page.nextpixel();
|
unsigned base = page.nextpixel();
|
||||||
if (base > 3);
|
if (base > 3) {
|
||||||
// throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit
|
derror();
|
||||||
// field, but....
|
}
|
||||||
if (base == 3)
|
if (base == 3) {
|
||||||
base = 4;
|
base = 4;
|
||||||
|
}
|
||||||
pixel_base = 0x200 << base;
|
pixel_base = 0x200 << base;
|
||||||
pmul = 1 << base;
|
pmul = 1 << base;
|
||||||
}
|
}
|
||||||
unsigned epixel = page.nextpixel();
|
unsigned epixel = page.nextpixel();
|
||||||
if (oddeven[pix % 2])
|
if (oddeven[pix % 2]) {
|
||||||
{
|
|
||||||
epixel *= pmul;
|
epixel *= pmul;
|
||||||
if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base)
|
if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) {
|
||||||
epixel += nonzero[pix % 2] - pixel_base;
|
epixel += nonzero[pix % 2] - pixel_base;
|
||||||
nonzero[pix % 2] = epixel;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
oddeven[pix % 2] = epixel;
|
|
||||||
if (epixel)
|
|
||||||
nonzero[pix % 2] = epixel;
|
nonzero[pix % 2] = epixel;
|
||||||
else
|
} else {
|
||||||
|
oddeven[pix % 2] = epixel;
|
||||||
|
if (epixel) {
|
||||||
|
nonzero[pix % 2] = epixel;
|
||||||
|
} else {
|
||||||
epixel = nonzero[pix % 2];
|
epixel = nonzero[pix % 2];
|
||||||
}
|
}
|
||||||
unsigned spix = epixel - 0xf;
|
}
|
||||||
if (spix <= 0xffff)
|
const unsigned spix = epixel - 0xf;
|
||||||
|
if (spix <= 0xffff) {
|
||||||
rowptr[col++] = spix & 0xffff;
|
rowptr[col++] = spix & 0xffff;
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f);
|
epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f);
|
||||||
rowptr[col++] = epixel & 0x3fff;
|
rowptr[col++] = epixel & 0x3fff;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user