|
|
@ -32,11 +32,11 @@
|
|
|
|
* JPEG-2000 Plugin for KImageIO.
|
|
|
|
* JPEG-2000 Plugin for KImageIO.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Current limitations:
|
|
|
|
* Current limitations:
|
|
|
|
* - Only reads sRGB/Grayscale images (doesn't convert colorspace).
|
|
|
|
|
|
|
|
* - Doesn't support writing images.
|
|
|
|
* - Doesn't support writing images.
|
|
|
|
* - Doesn't support OPJ_CODEC_J2K.
|
|
|
|
* - Doesn't support OPJ_CODEC_J2K.
|
|
|
|
* - Doesn't support subsampling.
|
|
|
|
* - Doesn't support subsampling.
|
|
|
|
* - Doesn't read ICC profiles.
|
|
|
|
* - Doesn't read ICC profiles.
|
|
|
|
|
|
|
|
* - Doesn't support esycc or cymk colorspaces.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* The API documentation is rather poor, so good references on how to use OpenJPEG
|
|
|
|
* The API documentation is rather poor, so good references on how to use OpenJPEG
|
|
|
|
* are the tools provided by OpenJPEG, such as 'opj_decompress':
|
|
|
|
* are the tools provided by OpenJPEG, such as 'opj_decompress':
|
|
|
@ -72,6 +72,460 @@ struct KIMGJP2Wrapper
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* The following sycc* functions come from OpenJPEG
|
|
|
|
|
|
|
|
* https://github.com/uclouvain/openjpeg/blob/master/src/bin/common/color.c
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* It has beens slightly adjusted to better fit the code style of this file.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* The copyright in this software is being made available under the 2-clauses
|
|
|
|
|
|
|
|
* BSD License, included below. This software may be subject to other third
|
|
|
|
|
|
|
|
* party and contributor rights, including patent rights, and no such rights
|
|
|
|
|
|
|
|
* are granted under this license.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
|
|
|
|
|
|
|
|
* Copyright (c) 2002-2014, Professor Benoit Macq
|
|
|
|
|
|
|
|
* Copyright (c) 2001-2003, David Janssens
|
|
|
|
|
|
|
|
* Copyright (c) 2002-2003, Yannick Verschueren
|
|
|
|
|
|
|
|
* Copyright (c) 2003-2007, Francois-Olivier Devaux
|
|
|
|
|
|
|
|
* Copyright (c) 2003-2014, Antonin Descampe
|
|
|
|
|
|
|
|
* Copyright (c) 2005, Herve Drolon, FreeImage Team
|
|
|
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
|
|
|
|
* are met:
|
|
|
|
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
|
|
|
|
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void sycc_to_rgb(int offset, int upb, int y, int cb, int cr,
|
|
|
|
|
|
|
|
int *out_r, int *out_g, int *out_b)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int r, g, b;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cb -= offset;
|
|
|
|
|
|
|
|
cr -= offset;
|
|
|
|
|
|
|
|
r = y + (int)(1.402 * (float)cr);
|
|
|
|
|
|
|
|
if (r < 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
r = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (r > upb)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
r = upb;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_r = r;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr);
|
|
|
|
|
|
|
|
if (g < 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
g = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (g > upb)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
g = upb;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_g = g;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
b = y + (int)(1.772 * (float)cb);
|
|
|
|
|
|
|
|
if (b < 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
b = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (b > upb)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
b = upb;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*out_b = b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool sycc444_to_rgb(opj_image_t *img)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int *d0, *d1, *d2, *r, *g, *b;
|
|
|
|
|
|
|
|
const int *y, *cb, *cr;
|
|
|
|
|
|
|
|
size_t maxw, maxh, max, i;
|
|
|
|
|
|
|
|
int offset, upb;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
upb = (int)img->comps[0].prec;
|
|
|
|
|
|
|
|
offset = 1 << (upb - 1);
|
|
|
|
|
|
|
|
upb = (1 << upb) - 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maxw = (size_t)img->comps[0].w;
|
|
|
|
|
|
|
|
maxh = (size_t)img->comps[0].h;
|
|
|
|
|
|
|
|
max = maxw * maxh;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
y = img->comps[0].data;
|
|
|
|
|
|
|
|
cb = img->comps[1].data;
|
|
|
|
|
|
|
|
cr = img->comps[2].data;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d0 = r = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
d1 = g = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
d2 = b = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (r == nullptr || g == nullptr || b == nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
goto fails;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0U; i < max; ++i)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++cb;
|
|
|
|
|
|
|
|
++cr;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[0].data);
|
|
|
|
|
|
|
|
img->comps[0].data = d0;
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[1].data);
|
|
|
|
|
|
|
|
img->comps[1].data = d1;
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[2].data);
|
|
|
|
|
|
|
|
img->comps[2].data = d2;
|
|
|
|
|
|
|
|
img->color_space = OPJ_CLRSPC_SRGB;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fails:
|
|
|
|
|
|
|
|
opj_image_data_free(r);
|
|
|
|
|
|
|
|
opj_image_data_free(g);
|
|
|
|
|
|
|
|
opj_image_data_free(b);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool sycc422_to_rgb(opj_image_t *img)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int *d0, *d1, *d2, *r, *g, *b;
|
|
|
|
|
|
|
|
const int *y, *cb, *cr;
|
|
|
|
|
|
|
|
size_t maxw, maxh, max, offx, loopmaxw;
|
|
|
|
|
|
|
|
int offset, upb;
|
|
|
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
upb = (int)img->comps[0].prec;
|
|
|
|
|
|
|
|
offset = 1 << (upb - 1);
|
|
|
|
|
|
|
|
upb = (1 << upb) - 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maxw = (size_t)img->comps[0].w;
|
|
|
|
|
|
|
|
maxh = (size_t)img->comps[0].h;
|
|
|
|
|
|
|
|
max = maxw * maxh;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
y = img->comps[0].data;
|
|
|
|
|
|
|
|
cb = img->comps[1].data;
|
|
|
|
|
|
|
|
cr = img->comps[2].data;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d0 = r = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
d1 = g = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
d2 = b = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (r == nullptr || g == nullptr || b == nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
goto fails;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if img->x0 is odd, then first column shall use Cb/Cr = 0 */
|
|
|
|
|
|
|
|
offx = img->x0 & 1U;
|
|
|
|
|
|
|
|
loopmaxw = maxw - offx;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0U; i < maxh; ++i)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (offx > 0U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, 0, 0, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (j = 0U; j < (loopmaxw & ~(size_t)1U); j += 2U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
++cb;
|
|
|
|
|
|
|
|
++cr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j < loopmaxw)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
++cb;
|
|
|
|
|
|
|
|
++cr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[0].data);
|
|
|
|
|
|
|
|
img->comps[0].data = d0;
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[1].data);
|
|
|
|
|
|
|
|
img->comps[1].data = d1;
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[2].data);
|
|
|
|
|
|
|
|
img->comps[2].data = d2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
img->comps[1].w = img->comps[2].w = img->comps[0].w;
|
|
|
|
|
|
|
|
img->comps[1].h = img->comps[2].h = img->comps[0].h;
|
|
|
|
|
|
|
|
img->comps[1].dx = img->comps[2].dx = img->comps[0].dx;
|
|
|
|
|
|
|
|
img->comps[1].dy = img->comps[2].dy = img->comps[0].dy;
|
|
|
|
|
|
|
|
img->color_space = OPJ_CLRSPC_SRGB;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fails:
|
|
|
|
|
|
|
|
opj_image_data_free(r);
|
|
|
|
|
|
|
|
opj_image_data_free(g);
|
|
|
|
|
|
|
|
opj_image_data_free(b);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool sycc420_to_rgb(opj_image_t *img)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int *d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
|
|
|
|
|
|
|
|
const int *y, *cb, *cr, *ny;
|
|
|
|
|
|
|
|
size_t maxw, maxh, max, offx, loopmaxw, offy, loopmaxh;
|
|
|
|
|
|
|
|
int offset, upb;
|
|
|
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
upb = (int)img->comps[0].prec;
|
|
|
|
|
|
|
|
offset = 1 << (upb - 1);
|
|
|
|
|
|
|
|
upb = (1 << upb) - 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maxw = (size_t)img->comps[0].w;
|
|
|
|
|
|
|
|
maxh = (size_t)img->comps[0].h;
|
|
|
|
|
|
|
|
max = maxw * maxh;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
y = img->comps[0].data;
|
|
|
|
|
|
|
|
cb = img->comps[1].data;
|
|
|
|
|
|
|
|
cr = img->comps[2].data;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d0 = r = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
d1 = g = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
d2 = b = (int*)opj_image_data_alloc(sizeof(int) * max);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (r == nullptr || g == nullptr || b == nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
goto fails;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if img->x0 is odd, then first column shall use Cb/Cr = 0 */
|
|
|
|
|
|
|
|
offx = img->x0 & 1U;
|
|
|
|
|
|
|
|
loopmaxw = maxw - offx;
|
|
|
|
|
|
|
|
/* if img->y0 is odd, then first line shall use Cb/Cr = 0 */
|
|
|
|
|
|
|
|
offy = img->y0 & 1U;
|
|
|
|
|
|
|
|
loopmaxh = maxh - offy;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (offy > 0U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < maxw; ++j)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, 0, 0, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0U; i < (loopmaxh & ~(size_t)1U); i += 2U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ny = y + maxw;
|
|
|
|
|
|
|
|
nr = r + maxw;
|
|
|
|
|
|
|
|
ng = g + maxw;
|
|
|
|
|
|
|
|
nb = b + maxw;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (offx > 0U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, 0, 0, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
|
|
|
|
|
|
|
++ny;
|
|
|
|
|
|
|
|
++nr;
|
|
|
|
|
|
|
|
++ng;
|
|
|
|
|
|
|
|
++nb;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < (loopmaxw & ~(size_t)1U); j += 2U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
|
|
|
|
|
|
|
++ny;
|
|
|
|
|
|
|
|
++nr;
|
|
|
|
|
|
|
|
++ng;
|
|
|
|
|
|
|
|
++nb;
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
|
|
|
|
|
|
|
++ny;
|
|
|
|
|
|
|
|
++nr;
|
|
|
|
|
|
|
|
++ng;
|
|
|
|
|
|
|
|
++nb;
|
|
|
|
|
|
|
|
++cb;
|
|
|
|
|
|
|
|
++cr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j < loopmaxw)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
|
|
|
|
|
|
|
|
++ny;
|
|
|
|
|
|
|
|
++nr;
|
|
|
|
|
|
|
|
++ng;
|
|
|
|
|
|
|
|
++nb;
|
|
|
|
|
|
|
|
++cb;
|
|
|
|
|
|
|
|
++cr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
y += maxw;
|
|
|
|
|
|
|
|
r += maxw;
|
|
|
|
|
|
|
|
g += maxw;
|
|
|
|
|
|
|
|
b += maxw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i < loopmaxh)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (offx > 0U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, 0, 0, r, g, b);
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (j = 0U; j < (loopmaxw & ~(size_t)1U); j += 2U)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
++y;
|
|
|
|
|
|
|
|
++r;
|
|
|
|
|
|
|
|
++g;
|
|
|
|
|
|
|
|
++b;
|
|
|
|
|
|
|
|
++cb;
|
|
|
|
|
|
|
|
++cr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (j < loopmaxw)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[0].data);
|
|
|
|
|
|
|
|
img->comps[0].data = d0;
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[1].data);
|
|
|
|
|
|
|
|
img->comps[1].data = d1;
|
|
|
|
|
|
|
|
opj_image_data_free(img->comps[2].data);
|
|
|
|
|
|
|
|
img->comps[2].data = d2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
img->comps[1].w = img->comps[2].w = img->comps[0].w;
|
|
|
|
|
|
|
|
img->comps[1].h = img->comps[2].h = img->comps[0].h;
|
|
|
|
|
|
|
|
img->comps[1].dx = img->comps[2].dx = img->comps[0].dx;
|
|
|
|
|
|
|
|
img->comps[1].dy = img->comps[2].dy = img->comps[0].dy;
|
|
|
|
|
|
|
|
img->color_space = OPJ_CLRSPC_SRGB;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fails:
|
|
|
|
|
|
|
|
opj_image_data_free(r);
|
|
|
|
|
|
|
|
opj_image_data_free(g);
|
|
|
|
|
|
|
|
opj_image_data_free(b);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool color_sycc_to_rgb(opj_image_t *img)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (img->numcomps < 3)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
img->color_space = OPJ_CLRSPC_GRAY;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((img->comps[0].dx == 1) &&
|
|
|
|
|
|
|
|
(img->comps[1].dx == 2) &&
|
|
|
|
|
|
|
|
(img->comps[2].dx == 2) &&
|
|
|
|
|
|
|
|
(img->comps[0].dy == 1) &&
|
|
|
|
|
|
|
|
(img->comps[1].dy == 2) &&
|
|
|
|
|
|
|
|
(img->comps[2].dy == 2))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* horizontal and vertical sub-sample */
|
|
|
|
|
|
|
|
return sycc420_to_rgb(img);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ((img->comps[0].dx == 1) &&
|
|
|
|
|
|
|
|
(img->comps[1].dx == 2) &&
|
|
|
|
|
|
|
|
(img->comps[2].dx == 2) &&
|
|
|
|
|
|
|
|
(img->comps[0].dy == 1) &&
|
|
|
|
|
|
|
|
(img->comps[1].dy == 1) &&
|
|
|
|
|
|
|
|
(img->comps[2].dy == 1))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* horizontal sub-sample only */
|
|
|
|
|
|
|
|
return sycc422_to_rgb(img);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ((img->comps[0].dx == 1) &&
|
|
|
|
|
|
|
|
(img->comps[1].dx == 1) &&
|
|
|
|
|
|
|
|
(img->comps[2].dx == 1) &&
|
|
|
|
|
|
|
|
(img->comps[0].dy == 1) &&
|
|
|
|
|
|
|
|
(img->comps[1].dy == 1) &&
|
|
|
|
|
|
|
|
(img->comps[2].dy == 1))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* no sub-sample */
|
|
|
|
|
|
|
|
return sycc444_to_rgb(img);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
kdWarning(kCategory) << "Can not convert in color_sycc_to_rgb" << endl;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void kimgio_jp2_err_handler(const char *message, void *data)
|
|
|
|
static void kimgio_jp2_err_handler(const char *message, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
kdError(kCategory) << "Error decoding JP2 image: " << message;
|
|
|
|
kdError(kCategory) << "Error decoding JP2 image: " << message;
|
|
|
@ -301,6 +755,17 @@ TDE_EXPORT void kimgio_jp2_read(TQImageIO* io)
|
|
|
|
kimgio_jp2_read_image(image, jp2);
|
|
|
|
kimgio_jp2_read_image(image, jp2);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case OPJ_CLRSPC_SYCC:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (false == color_sycc_to_rgb(jp2.image))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
kdError(kCategory) << "Could not convert YCbCr JP2 encoded image to sRGB." << endl;
|
|
|
|
|
|
|
|
io->setStatus(IO_UnspecifiedError);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
kimgio_jp2_read_image(image, jp2);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
kdError(kCategory) << "Unsupported colorspace detected: "
|
|
|
|
kdError(kCategory) << "Unsupported colorspace detected: "
|
|
|
|