1*ec63e07aSXin Li--- convert.c 2020-08-27 15:46:32.911584344 +0000 2*ec63e07aSXin Li+++ convert_helper.cc 2020-08-27 15:10:52.695231032 +0000 3*ec63e07aSXin Li@@ -35,2605 +35,311 @@ 4*ec63e07aSXin Li * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 5*ec63e07aSXin Li * POSSIBILITY OF SUCH DAMAGE. 6*ec63e07aSXin Li */ 7*ec63e07aSXin Li-#include "opj_apps_config.h" 8*ec63e07aSXin Li 9*ec63e07aSXin Li-#include <stdio.h> 10*ec63e07aSXin Li-#include <stdlib.h> 11*ec63e07aSXin Li-#include <string.h> 12*ec63e07aSXin Li-#include <ctype.h> 13*ec63e07aSXin Li-#include <limits.h> 14*ec63e07aSXin Li- 15*ec63e07aSXin Li-#include "openjpeg.h" 16*ec63e07aSXin Li-#include "convert.h" 17*ec63e07aSXin Li- 18*ec63e07aSXin Li-/* 19*ec63e07aSXin Li- * Get logarithm of an integer and round downwards. 20*ec63e07aSXin Li- * 21*ec63e07aSXin Li- * log2(a) 22*ec63e07aSXin Li- */ 23*ec63e07aSXin Li-static int int_floorlog2(int a) 24*ec63e07aSXin Li-{ 25*ec63e07aSXin Li- int l; 26*ec63e07aSXin Li- for (l = 0; a > 1; l++) { 27*ec63e07aSXin Li- a >>= 1; 28*ec63e07aSXin Li- } 29*ec63e07aSXin Li- return l; 30*ec63e07aSXin Li-} 31*ec63e07aSXin Li- 32*ec63e07aSXin Li-/* Component precision scaling */ 33*ec63e07aSXin Li-void clip_component(opj_image_comp_t* component, OPJ_UINT32 precision) 34*ec63e07aSXin Li-{ 35*ec63e07aSXin Li- OPJ_SIZE_T i; 36*ec63e07aSXin Li- OPJ_SIZE_T len; 37*ec63e07aSXin Li- OPJ_UINT32 umax = (OPJ_UINT32)((OPJ_INT32) - 1); 38*ec63e07aSXin Li- 39*ec63e07aSXin Li- len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h; 40*ec63e07aSXin Li- if (precision < 32) { 41*ec63e07aSXin Li- umax = (1U << precision) - 1U; 42*ec63e07aSXin Li- } 43*ec63e07aSXin Li- 44*ec63e07aSXin Li- if (component->sgnd) { 45*ec63e07aSXin Li- OPJ_INT32* l_data = component->data; 46*ec63e07aSXin Li- OPJ_INT32 max = (OPJ_INT32)(umax / 2U); 47*ec63e07aSXin Li- OPJ_INT32 min = -max - 1; 48*ec63e07aSXin Li- for (i = 0; i < len; ++i) { 49*ec63e07aSXin Li- if (l_data[i] > max) { 50*ec63e07aSXin Li- l_data[i] = max; 51*ec63e07aSXin Li- } else if (l_data[i] < min) { 52*ec63e07aSXin Li- l_data[i] = min; 53*ec63e07aSXin Li- } 54*ec63e07aSXin Li- } 55*ec63e07aSXin Li- } else { 56*ec63e07aSXin Li- OPJ_UINT32* l_data = (OPJ_UINT32*)component->data; 57*ec63e07aSXin Li- for (i = 0; i < len; ++i) { 58*ec63e07aSXin Li- if (l_data[i] > umax) { 59*ec63e07aSXin Li- l_data[i] = umax; 60*ec63e07aSXin Li- } 61*ec63e07aSXin Li- } 62*ec63e07aSXin Li- } 63*ec63e07aSXin Li- component->prec = precision; 64*ec63e07aSXin Li-} 65*ec63e07aSXin Li+// patched versions of a few library tools 66*ec63e07aSXin Li 67*ec63e07aSXin Li-/* Component precision scaling */ 68*ec63e07aSXin Li-static void scale_component_up(opj_image_comp_t* component, 69*ec63e07aSXin Li- OPJ_UINT32 precision) 70*ec63e07aSXin Li-{ 71*ec63e07aSXin Li- OPJ_SIZE_T i, len; 72*ec63e07aSXin Li- 73*ec63e07aSXin Li- len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h; 74*ec63e07aSXin Li- if (component->sgnd) { 75*ec63e07aSXin Li- OPJ_INT64 newMax = (OPJ_INT64)(1U << (precision - 1)); 76*ec63e07aSXin Li- OPJ_INT64 oldMax = (OPJ_INT64)(1U << (component->prec - 1)); 77*ec63e07aSXin Li- OPJ_INT32* l_data = component->data; 78*ec63e07aSXin Li- for (i = 0; i < len; ++i) { 79*ec63e07aSXin Li- l_data[i] = (OPJ_INT32)(((OPJ_INT64)l_data[i] * newMax) / oldMax); 80*ec63e07aSXin Li- } 81*ec63e07aSXin Li- } else { 82*ec63e07aSXin Li- OPJ_UINT64 newMax = (OPJ_UINT64)((1U << precision) - 1U); 83*ec63e07aSXin Li- OPJ_UINT64 oldMax = (OPJ_UINT64)((1U << component->prec) - 1U); 84*ec63e07aSXin Li- OPJ_UINT32* l_data = (OPJ_UINT32*)component->data; 85*ec63e07aSXin Li- for (i = 0; i < len; ++i) { 86*ec63e07aSXin Li- l_data[i] = (OPJ_UINT32)(((OPJ_UINT64)l_data[i] * newMax) / oldMax); 87*ec63e07aSXin Li- } 88*ec63e07aSXin Li- } 89*ec63e07aSXin Li- component->prec = precision; 90*ec63e07aSXin Li- component->bpp = precision; 91*ec63e07aSXin Li-} 92*ec63e07aSXin Li-void scale_component(opj_image_comp_t* component, OPJ_UINT32 precision) 93*ec63e07aSXin Li-{ 94*ec63e07aSXin Li- int shift; 95*ec63e07aSXin Li- OPJ_SIZE_T i, len; 96*ec63e07aSXin Li- 97*ec63e07aSXin Li- if (component->prec == precision) { 98*ec63e07aSXin Li- return; 99*ec63e07aSXin Li- } 100*ec63e07aSXin Li- if (component->prec < precision) { 101*ec63e07aSXin Li- scale_component_up(component, precision); 102*ec63e07aSXin Li- return; 103*ec63e07aSXin Li- } 104*ec63e07aSXin Li- shift = (int)(component->prec - precision); 105*ec63e07aSXin Li- len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h; 106*ec63e07aSXin Li- if (component->sgnd) { 107*ec63e07aSXin Li- OPJ_INT32* l_data = component->data; 108*ec63e07aSXin Li- for (i = 0; i < len; ++i) { 109*ec63e07aSXin Li- l_data[i] >>= shift; 110*ec63e07aSXin Li- } 111*ec63e07aSXin Li- } else { 112*ec63e07aSXin Li- OPJ_UINT32* l_data = (OPJ_UINT32*)component->data; 113*ec63e07aSXin Li- for (i = 0; i < len; ++i) { 114*ec63e07aSXin Li- l_data[i] >>= shift; 115*ec63e07aSXin Li- } 116*ec63e07aSXin Li- } 117*ec63e07aSXin Li- component->bpp = precision; 118*ec63e07aSXin Li- component->prec = precision; 119*ec63e07aSXin Li-} 120*ec63e07aSXin Li- 121*ec63e07aSXin Li- 122*ec63e07aSXin Li-/* planar / interleaved conversions */ 123*ec63e07aSXin Li-/* used by PNG/TIFF */ 124*ec63e07aSXin Li-static void convert_32s_C1P1(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, 125*ec63e07aSXin Li- OPJ_SIZE_T length) 126*ec63e07aSXin Li-{ 127*ec63e07aSXin Li- memcpy(pDst[0], pSrc, length * sizeof(OPJ_INT32)); 128*ec63e07aSXin Li-} 129*ec63e07aSXin Li-static void convert_32s_C2P2(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, 130*ec63e07aSXin Li- OPJ_SIZE_T length) 131*ec63e07aSXin Li-{ 132*ec63e07aSXin Li- OPJ_SIZE_T i; 133*ec63e07aSXin Li- OPJ_INT32* pDst0 = pDst[0]; 134*ec63e07aSXin Li- OPJ_INT32* pDst1 = pDst[1]; 135*ec63e07aSXin Li- 136*ec63e07aSXin Li- for (i = 0; i < length; i++) { 137*ec63e07aSXin Li- pDst0[i] = pSrc[2 * i + 0]; 138*ec63e07aSXin Li- pDst1[i] = pSrc[2 * i + 1]; 139*ec63e07aSXin Li- } 140*ec63e07aSXin Li-} 141*ec63e07aSXin Li-static void convert_32s_C3P3(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, 142*ec63e07aSXin Li- OPJ_SIZE_T length) 143*ec63e07aSXin Li-{ 144*ec63e07aSXin Li- OPJ_SIZE_T i; 145*ec63e07aSXin Li- OPJ_INT32* pDst0 = pDst[0]; 146*ec63e07aSXin Li- OPJ_INT32* pDst1 = pDst[1]; 147*ec63e07aSXin Li- OPJ_INT32* pDst2 = pDst[2]; 148*ec63e07aSXin Li- 149*ec63e07aSXin Li- for (i = 0; i < length; i++) { 150*ec63e07aSXin Li- pDst0[i] = pSrc[3 * i + 0]; 151*ec63e07aSXin Li- pDst1[i] = pSrc[3 * i + 1]; 152*ec63e07aSXin Li- pDst2[i] = pSrc[3 * i + 2]; 153*ec63e07aSXin Li- } 154*ec63e07aSXin Li-} 155*ec63e07aSXin Li-static void convert_32s_C4P4(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, 156*ec63e07aSXin Li- OPJ_SIZE_T length) 157*ec63e07aSXin Li-{ 158*ec63e07aSXin Li- OPJ_SIZE_T i; 159*ec63e07aSXin Li- OPJ_INT32* pDst0 = pDst[0]; 160*ec63e07aSXin Li- OPJ_INT32* pDst1 = pDst[1]; 161*ec63e07aSXin Li- OPJ_INT32* pDst2 = pDst[2]; 162*ec63e07aSXin Li- OPJ_INT32* pDst3 = pDst[3]; 163*ec63e07aSXin Li- 164*ec63e07aSXin Li- for (i = 0; i < length; i++) { 165*ec63e07aSXin Li- pDst0[i] = pSrc[4 * i + 0]; 166*ec63e07aSXin Li- pDst1[i] = pSrc[4 * i + 1]; 167*ec63e07aSXin Li- pDst2[i] = pSrc[4 * i + 2]; 168*ec63e07aSXin Li- pDst3[i] = pSrc[4 * i + 3]; 169*ec63e07aSXin Li- } 170*ec63e07aSXin Li-} 171*ec63e07aSXin Li-const convert_32s_CXPX convert_32s_CXPX_LUT[5] = { 172*ec63e07aSXin Li- NULL, 173*ec63e07aSXin Li- convert_32s_C1P1, 174*ec63e07aSXin Li- convert_32s_C2P2, 175*ec63e07aSXin Li- convert_32s_C3P3, 176*ec63e07aSXin Li- convert_32s_C4P4 177*ec63e07aSXin Li-}; 178*ec63e07aSXin Li- 179*ec63e07aSXin Li-static void convert_32s_P1C1(OPJ_INT32 const* const* pSrc, OPJ_INT32* pDst, 180*ec63e07aSXin Li- OPJ_SIZE_T length, OPJ_INT32 adjust) 181*ec63e07aSXin Li-{ 182*ec63e07aSXin Li- OPJ_SIZE_T i; 183*ec63e07aSXin Li- const OPJ_INT32* pSrc0 = pSrc[0]; 184*ec63e07aSXin Li+#include "convert.h" 185*ec63e07aSXin Li 186*ec63e07aSXin Li- for (i = 0; i < length; i++) { 187*ec63e07aSXin Li- pDst[i] = pSrc0[i] + adjust; 188*ec63e07aSXin Li- } 189*ec63e07aSXin Li-} 190*ec63e07aSXin Li-static void convert_32s_P2C2(OPJ_INT32 const* const* pSrc, OPJ_INT32* pDst, 191*ec63e07aSXin Li- OPJ_SIZE_T length, OPJ_INT32 adjust) 192*ec63e07aSXin Li-{ 193*ec63e07aSXin Li- OPJ_SIZE_T i; 194*ec63e07aSXin Li- const OPJ_INT32* pSrc0 = pSrc[0]; 195*ec63e07aSXin Li- const OPJ_INT32* pSrc1 = pSrc[1]; 196*ec63e07aSXin Li- 197*ec63e07aSXin Li- for (i = 0; i < length; i++) { 198*ec63e07aSXin Li- pDst[2 * i + 0] = pSrc0[i] + adjust; 199*ec63e07aSXin Li- pDst[2 * i + 1] = pSrc1[i] + adjust; 200*ec63e07aSXin Li- } 201*ec63e07aSXin Li-} 202*ec63e07aSXin Li-static void convert_32s_P3C3(OPJ_INT32 const* const* pSrc, OPJ_INT32* pDst, 203*ec63e07aSXin Li- OPJ_SIZE_T length, OPJ_INT32 adjust) 204*ec63e07aSXin Li-{ 205*ec63e07aSXin Li- OPJ_SIZE_T i; 206*ec63e07aSXin Li- const OPJ_INT32* pSrc0 = pSrc[0]; 207*ec63e07aSXin Li- const OPJ_INT32* pSrc1 = pSrc[1]; 208*ec63e07aSXin Li- const OPJ_INT32* pSrc2 = pSrc[2]; 209*ec63e07aSXin Li- 210*ec63e07aSXin Li- for (i = 0; i < length; i++) { 211*ec63e07aSXin Li- pDst[3 * i + 0] = pSrc0[i] + adjust; 212*ec63e07aSXin Li- pDst[3 * i + 1] = pSrc1[i] + adjust; 213*ec63e07aSXin Li- pDst[3 * i + 2] = pSrc2[i] + adjust; 214*ec63e07aSXin Li- } 215*ec63e07aSXin Li-} 216*ec63e07aSXin Li-static void convert_32s_P4C4(OPJ_INT32 const* const* pSrc, OPJ_INT32* pDst, 217*ec63e07aSXin Li- OPJ_SIZE_T length, OPJ_INT32 adjust) 218*ec63e07aSXin Li-{ 219*ec63e07aSXin Li- OPJ_SIZE_T i; 220*ec63e07aSXin Li- const OPJ_INT32* pSrc0 = pSrc[0]; 221*ec63e07aSXin Li- const OPJ_INT32* pSrc1 = pSrc[1]; 222*ec63e07aSXin Li- const OPJ_INT32* pSrc2 = pSrc[2]; 223*ec63e07aSXin Li- const OPJ_INT32* pSrc3 = pSrc[3]; 224*ec63e07aSXin Li- 225*ec63e07aSXin Li- for (i = 0; i < length; i++) { 226*ec63e07aSXin Li- pDst[4 * i + 0] = pSrc0[i] + adjust; 227*ec63e07aSXin Li- pDst[4 * i + 1] = pSrc1[i] + adjust; 228*ec63e07aSXin Li- pDst[4 * i + 2] = pSrc2[i] + adjust; 229*ec63e07aSXin Li- pDst[4 * i + 3] = pSrc3[i] + adjust; 230*ec63e07aSXin Li- } 231*ec63e07aSXin Li-} 232*ec63e07aSXin Li-const convert_32s_PXCX convert_32s_PXCX_LUT[5] = { 233*ec63e07aSXin Li- NULL, 234*ec63e07aSXin Li- convert_32s_P1C1, 235*ec63e07aSXin Li- convert_32s_P2C2, 236*ec63e07aSXin Li- convert_32s_P3C3, 237*ec63e07aSXin Li- convert_32s_P4C4 238*ec63e07aSXin Li-}; 239*ec63e07aSXin Li- 240*ec63e07aSXin Li-/* bit depth conversions */ 241*ec63e07aSXin Li-/* used by PNG/TIFF up to 8bpp */ 242*ec63e07aSXin Li-static void convert_1u32s_C1R(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, 243*ec63e07aSXin Li- OPJ_SIZE_T length) 244*ec63e07aSXin Li-{ 245*ec63e07aSXin Li- OPJ_SIZE_T i; 246*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)7U); i += 8U) { 247*ec63e07aSXin Li- OPJ_UINT32 val = *pSrc++; 248*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val >> 7); 249*ec63e07aSXin Li- pDst[i + 1] = (OPJ_INT32)((val >> 6) & 0x1U); 250*ec63e07aSXin Li- pDst[i + 2] = (OPJ_INT32)((val >> 5) & 0x1U); 251*ec63e07aSXin Li- pDst[i + 3] = (OPJ_INT32)((val >> 4) & 0x1U); 252*ec63e07aSXin Li- pDst[i + 4] = (OPJ_INT32)((val >> 3) & 0x1U); 253*ec63e07aSXin Li- pDst[i + 5] = (OPJ_INT32)((val >> 2) & 0x1U); 254*ec63e07aSXin Li- pDst[i + 6] = (OPJ_INT32)((val >> 1) & 0x1U); 255*ec63e07aSXin Li- pDst[i + 7] = (OPJ_INT32)(val & 0x1U); 256*ec63e07aSXin Li- } 257*ec63e07aSXin Li- if (length & 7U) { 258*ec63e07aSXin Li- OPJ_UINT32 val = *pSrc++; 259*ec63e07aSXin Li- length = length & 7U; 260*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val >> 7); 261*ec63e07aSXin Li- 262*ec63e07aSXin Li- if (length > 1U) { 263*ec63e07aSXin Li- pDst[i + 1] = (OPJ_INT32)((val >> 6) & 0x1U); 264*ec63e07aSXin Li- if (length > 2U) { 265*ec63e07aSXin Li- pDst[i + 2] = (OPJ_INT32)((val >> 5) & 0x1U); 266*ec63e07aSXin Li- if (length > 3U) { 267*ec63e07aSXin Li- pDst[i + 3] = (OPJ_INT32)((val >> 4) & 0x1U); 268*ec63e07aSXin Li- if (length > 4U) { 269*ec63e07aSXin Li- pDst[i + 4] = (OPJ_INT32)((val >> 3) & 0x1U); 270*ec63e07aSXin Li- if (length > 5U) { 271*ec63e07aSXin Li- pDst[i + 5] = (OPJ_INT32)((val >> 2) & 0x1U); 272*ec63e07aSXin Li- if (length > 6U) { 273*ec63e07aSXin Li- pDst[i + 6] = (OPJ_INT32)((val >> 1) & 0x1U); 274*ec63e07aSXin Li- } 275*ec63e07aSXin Li- } 276*ec63e07aSXin Li- } 277*ec63e07aSXin Li- } 278*ec63e07aSXin Li- } 279*ec63e07aSXin Li- } 280*ec63e07aSXin Li- } 281*ec63e07aSXin Li-} 282*ec63e07aSXin Li-static void convert_2u32s_C1R(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, 283*ec63e07aSXin Li- OPJ_SIZE_T length) 284*ec63e07aSXin Li-{ 285*ec63e07aSXin Li- OPJ_SIZE_T i; 286*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)3U); i += 4U) { 287*ec63e07aSXin Li- OPJ_UINT32 val = *pSrc++; 288*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val >> 6); 289*ec63e07aSXin Li- pDst[i + 1] = (OPJ_INT32)((val >> 4) & 0x3U); 290*ec63e07aSXin Li- pDst[i + 2] = (OPJ_INT32)((val >> 2) & 0x3U); 291*ec63e07aSXin Li- pDst[i + 3] = (OPJ_INT32)(val & 0x3U); 292*ec63e07aSXin Li- } 293*ec63e07aSXin Li- if (length & 3U) { 294*ec63e07aSXin Li- OPJ_UINT32 val = *pSrc++; 295*ec63e07aSXin Li- length = length & 3U; 296*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val >> 6); 297*ec63e07aSXin Li- 298*ec63e07aSXin Li- if (length > 1U) { 299*ec63e07aSXin Li- pDst[i + 1] = (OPJ_INT32)((val >> 4) & 0x3U); 300*ec63e07aSXin Li- if (length > 2U) { 301*ec63e07aSXin Li- pDst[i + 2] = (OPJ_INT32)((val >> 2) & 0x3U); 302*ec63e07aSXin Li+#define OPJ_TRUE 1 303*ec63e07aSXin Li+#define OPJ_FALSE 0 304*ec63e07aSXin Li 305*ec63e07aSXin Li- } 306*ec63e07aSXin Li- } 307*ec63e07aSXin Li- } 308*ec63e07aSXin Li-} 309*ec63e07aSXin Li-static void convert_4u32s_C1R(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, 310*ec63e07aSXin Li- OPJ_SIZE_T length) 311*ec63e07aSXin Li-{ 312*ec63e07aSXin Li- OPJ_SIZE_T i; 313*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)1U); i += 2U) { 314*ec63e07aSXin Li- OPJ_UINT32 val = *pSrc++; 315*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val >> 4); 316*ec63e07aSXin Li- pDst[i + 1] = (OPJ_INT32)(val & 0xFU); 317*ec63e07aSXin Li- } 318*ec63e07aSXin Li- if (length & 1U) { 319*ec63e07aSXin Li- OPJ_UINT8 val = *pSrc++; 320*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val >> 4); 321*ec63e07aSXin Li- } 322*ec63e07aSXin Li-} 323*ec63e07aSXin Li-static void convert_6u32s_C1R(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, 324*ec63e07aSXin Li- OPJ_SIZE_T length) 325*ec63e07aSXin Li-{ 326*ec63e07aSXin Li- OPJ_SIZE_T i; 327*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)3U); i += 4U) { 328*ec63e07aSXin Li- OPJ_UINT32 val0 = *pSrc++; 329*ec63e07aSXin Li- OPJ_UINT32 val1 = *pSrc++; 330*ec63e07aSXin Li- OPJ_UINT32 val2 = *pSrc++; 331*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val0 >> 2); 332*ec63e07aSXin Li- pDst[i + 1] = (OPJ_INT32)(((val0 & 0x3U) << 4) | (val1 >> 4)); 333*ec63e07aSXin Li- pDst[i + 2] = (OPJ_INT32)(((val1 & 0xFU) << 2) | (val2 >> 6)); 334*ec63e07aSXin Li- pDst[i + 3] = (OPJ_INT32)(val2 & 0x3FU); 335*ec63e07aSXin Li+const char *opj_version(void) { return "2.3.1"; } 336*ec63e07aSXin Li 337*ec63e07aSXin Li- } 338*ec63e07aSXin Li- if (length & 3U) { 339*ec63e07aSXin Li- OPJ_UINT32 val0 = *pSrc++; 340*ec63e07aSXin Li- length = length & 3U; 341*ec63e07aSXin Li- pDst[i + 0] = (OPJ_INT32)(val0 >> 2); 342*ec63e07aSXin Li- 343*ec63e07aSXin Li- if (length > 1U) { 344*ec63e07aSXin Li- OPJ_UINT32 val1 = *pSrc++; 345*ec63e07aSXin Li- pDst[i + 1] = (OPJ_INT32)(((val0 & 0x3U) << 4) | (val1 >> 4)); 346*ec63e07aSXin Li- if (length > 2U) { 347*ec63e07aSXin Li- OPJ_UINT32 val2 = *pSrc++; 348*ec63e07aSXin Li- pDst[i + 2] = (OPJ_INT32)(((val1 & 0xFU) << 2) | (val2 >> 6)); 349*ec63e07aSXin Li- } 350*ec63e07aSXin Li- } 351*ec63e07aSXin Li- } 352*ec63e07aSXin Li-} 353*ec63e07aSXin Li-static void convert_8u32s_C1R(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, 354*ec63e07aSXin Li- OPJ_SIZE_T length) 355*ec63e07aSXin Li-{ 356*ec63e07aSXin Li- OPJ_SIZE_T i; 357*ec63e07aSXin Li- for (i = 0; i < length; i++) { 358*ec63e07aSXin Li- pDst[i] = pSrc[i]; 359*ec63e07aSXin Li- } 360*ec63e07aSXin Li-} 361*ec63e07aSXin Li-const convert_XXx32s_C1R convert_XXu32s_C1R_LUT[9] = { 362*ec63e07aSXin Li- NULL, 363*ec63e07aSXin Li- convert_1u32s_C1R, 364*ec63e07aSXin Li- convert_2u32s_C1R, 365*ec63e07aSXin Li- NULL, 366*ec63e07aSXin Li- convert_4u32s_C1R, 367*ec63e07aSXin Li- NULL, 368*ec63e07aSXin Li- convert_6u32s_C1R, 369*ec63e07aSXin Li- NULL, 370*ec63e07aSXin Li- convert_8u32s_C1R 371*ec63e07aSXin Li-}; 372*ec63e07aSXin Li- 373*ec63e07aSXin Li- 374*ec63e07aSXin Li-static void convert_32s1u_C1R(const OPJ_INT32* pSrc, OPJ_BYTE* pDst, 375*ec63e07aSXin Li- OPJ_SIZE_T length) 376*ec63e07aSXin Li-{ 377*ec63e07aSXin Li- OPJ_SIZE_T i; 378*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)7U); i += 8U) { 379*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 380*ec63e07aSXin Li- OPJ_UINT32 src1 = (OPJ_UINT32)pSrc[i + 1]; 381*ec63e07aSXin Li- OPJ_UINT32 src2 = (OPJ_UINT32)pSrc[i + 2]; 382*ec63e07aSXin Li- OPJ_UINT32 src3 = (OPJ_UINT32)pSrc[i + 3]; 383*ec63e07aSXin Li- OPJ_UINT32 src4 = (OPJ_UINT32)pSrc[i + 4]; 384*ec63e07aSXin Li- OPJ_UINT32 src5 = (OPJ_UINT32)pSrc[i + 5]; 385*ec63e07aSXin Li- OPJ_UINT32 src6 = (OPJ_UINT32)pSrc[i + 6]; 386*ec63e07aSXin Li- OPJ_UINT32 src7 = (OPJ_UINT32)pSrc[i + 7]; 387*ec63e07aSXin Li- 388*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 7) | (src1 << 6) | (src2 << 5) | (src3 << 4) | 389*ec63e07aSXin Li- (src4 << 3) | (src5 << 2) | (src6 << 1) | src7); 390*ec63e07aSXin Li- } 391*ec63e07aSXin Li- 392*ec63e07aSXin Li- if (length & 7U) { 393*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 394*ec63e07aSXin Li- OPJ_UINT32 src1 = 0U; 395*ec63e07aSXin Li- OPJ_UINT32 src2 = 0U; 396*ec63e07aSXin Li- OPJ_UINT32 src3 = 0U; 397*ec63e07aSXin Li- OPJ_UINT32 src4 = 0U; 398*ec63e07aSXin Li- OPJ_UINT32 src5 = 0U; 399*ec63e07aSXin Li- OPJ_UINT32 src6 = 0U; 400*ec63e07aSXin Li- length = length & 7U; 401*ec63e07aSXin Li- 402*ec63e07aSXin Li- if (length > 1U) { 403*ec63e07aSXin Li- src1 = (OPJ_UINT32)pSrc[i + 1]; 404*ec63e07aSXin Li- if (length > 2U) { 405*ec63e07aSXin Li- src2 = (OPJ_UINT32)pSrc[i + 2]; 406*ec63e07aSXin Li- if (length > 3U) { 407*ec63e07aSXin Li- src3 = (OPJ_UINT32)pSrc[i + 3]; 408*ec63e07aSXin Li- if (length > 4U) { 409*ec63e07aSXin Li- src4 = (OPJ_UINT32)pSrc[i + 4]; 410*ec63e07aSXin Li- if (length > 5U) { 411*ec63e07aSXin Li- src5 = (OPJ_UINT32)pSrc[i + 5]; 412*ec63e07aSXin Li- if (length > 6U) { 413*ec63e07aSXin Li- src6 = (OPJ_UINT32)pSrc[i + 6]; 414*ec63e07aSXin Li- } 415*ec63e07aSXin Li- } 416*ec63e07aSXin Li- } 417*ec63e07aSXin Li- } 418*ec63e07aSXin Li- } 419*ec63e07aSXin Li- } 420*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 7) | (src1 << 6) | (src2 << 5) | (src3 << 4) | 421*ec63e07aSXin Li- (src4 << 3) | (src5 << 2) | (src6 << 1)); 422*ec63e07aSXin Li- } 423*ec63e07aSXin Li-} 424*ec63e07aSXin Li- 425*ec63e07aSXin Li-static void convert_32s2u_C1R(const OPJ_INT32* pSrc, OPJ_BYTE* pDst, 426*ec63e07aSXin Li- OPJ_SIZE_T length) 427*ec63e07aSXin Li-{ 428*ec63e07aSXin Li- OPJ_SIZE_T i; 429*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)3U); i += 4U) { 430*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 431*ec63e07aSXin Li- OPJ_UINT32 src1 = (OPJ_UINT32)pSrc[i + 1]; 432*ec63e07aSXin Li- OPJ_UINT32 src2 = (OPJ_UINT32)pSrc[i + 2]; 433*ec63e07aSXin Li- OPJ_UINT32 src3 = (OPJ_UINT32)pSrc[i + 3]; 434*ec63e07aSXin Li- 435*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 6) | (src1 << 4) | (src2 << 2) | src3); 436*ec63e07aSXin Li- } 437*ec63e07aSXin Li- 438*ec63e07aSXin Li- if (length & 3U) { 439*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 440*ec63e07aSXin Li- OPJ_UINT32 src1 = 0U; 441*ec63e07aSXin Li- OPJ_UINT32 src2 = 0U; 442*ec63e07aSXin Li- length = length & 3U; 443*ec63e07aSXin Li- 444*ec63e07aSXin Li- if (length > 1U) { 445*ec63e07aSXin Li- src1 = (OPJ_UINT32)pSrc[i + 1]; 446*ec63e07aSXin Li- if (length > 2U) { 447*ec63e07aSXin Li- src2 = (OPJ_UINT32)pSrc[i + 2]; 448*ec63e07aSXin Li- } 449*ec63e07aSXin Li- } 450*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 6) | (src1 << 4) | (src2 << 2)); 451*ec63e07aSXin Li- } 452*ec63e07aSXin Li-} 453*ec63e07aSXin Li- 454*ec63e07aSXin Li-static void convert_32s4u_C1R(const OPJ_INT32* pSrc, OPJ_BYTE* pDst, 455*ec63e07aSXin Li- OPJ_SIZE_T length) 456*ec63e07aSXin Li-{ 457*ec63e07aSXin Li- OPJ_SIZE_T i; 458*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)1U); i += 2U) { 459*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 460*ec63e07aSXin Li- OPJ_UINT32 src1 = (OPJ_UINT32)pSrc[i + 1]; 461*ec63e07aSXin Li- 462*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 4) | src1); 463*ec63e07aSXin Li- } 464*ec63e07aSXin Li- 465*ec63e07aSXin Li- if (length & 1U) { 466*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 467*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 4)); 468*ec63e07aSXin Li- } 469*ec63e07aSXin Li-} 470*ec63e07aSXin Li- 471*ec63e07aSXin Li-static void convert_32s6u_C1R(const OPJ_INT32* pSrc, OPJ_BYTE* pDst, 472*ec63e07aSXin Li- OPJ_SIZE_T length) 473*ec63e07aSXin Li-{ 474*ec63e07aSXin Li- OPJ_SIZE_T i; 475*ec63e07aSXin Li- for (i = 0; i < (length & ~(OPJ_SIZE_T)3U); i += 4U) { 476*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 477*ec63e07aSXin Li- OPJ_UINT32 src1 = (OPJ_UINT32)pSrc[i + 1]; 478*ec63e07aSXin Li- OPJ_UINT32 src2 = (OPJ_UINT32)pSrc[i + 2]; 479*ec63e07aSXin Li- OPJ_UINT32 src3 = (OPJ_UINT32)pSrc[i + 3]; 480*ec63e07aSXin Li- 481*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 2) | (src1 >> 4)); 482*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)(((src1 & 0xFU) << 4) | (src2 >> 2)); 483*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)(((src2 & 0x3U) << 6) | src3); 484*ec63e07aSXin Li- } 485*ec63e07aSXin Li- 486*ec63e07aSXin Li- if (length & 3U) { 487*ec63e07aSXin Li- OPJ_UINT32 src0 = (OPJ_UINT32)pSrc[i + 0]; 488*ec63e07aSXin Li- OPJ_UINT32 src1 = 0U; 489*ec63e07aSXin Li- OPJ_UINT32 src2 = 0U; 490*ec63e07aSXin Li- length = length & 3U; 491*ec63e07aSXin Li- 492*ec63e07aSXin Li- if (length > 1U) { 493*ec63e07aSXin Li- src1 = (OPJ_UINT32)pSrc[i + 1]; 494*ec63e07aSXin Li- if (length > 2U) { 495*ec63e07aSXin Li- src2 = (OPJ_UINT32)pSrc[i + 2]; 496*ec63e07aSXin Li- } 497*ec63e07aSXin Li- } 498*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)((src0 << 2) | (src1 >> 4)); 499*ec63e07aSXin Li- if (length > 1U) { 500*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)(((src1 & 0xFU) << 4) | (src2 >> 2)); 501*ec63e07aSXin Li- if (length > 2U) { 502*ec63e07aSXin Li- *pDst++ = (OPJ_BYTE)(((src2 & 0x3U) << 6)); 503*ec63e07aSXin Li- } 504*ec63e07aSXin Li- } 505*ec63e07aSXin Li- } 506*ec63e07aSXin Li-} 507*ec63e07aSXin Li-static void convert_32s8u_C1R(const OPJ_INT32* pSrc, OPJ_BYTE* pDst, 508*ec63e07aSXin Li- OPJ_SIZE_T length) 509*ec63e07aSXin Li-{ 510*ec63e07aSXin Li- OPJ_SIZE_T i; 511*ec63e07aSXin Li- for (i = 0; i < length; ++i) { 512*ec63e07aSXin Li- pDst[i] = (OPJ_BYTE)pSrc[i]; 513*ec63e07aSXin Li- } 514*ec63e07aSXin Li-} 515*ec63e07aSXin Li-const convert_32sXXx_C1R convert_32sXXu_C1R_LUT[9] = { 516*ec63e07aSXin Li- NULL, 517*ec63e07aSXin Li- convert_32s1u_C1R, 518*ec63e07aSXin Li- convert_32s2u_C1R, 519*ec63e07aSXin Li- NULL, 520*ec63e07aSXin Li- convert_32s4u_C1R, 521*ec63e07aSXin Li- NULL, 522*ec63e07aSXin Li- convert_32s6u_C1R, 523*ec63e07aSXin Li- NULL, 524*ec63e07aSXin Li- convert_32s8u_C1R 525*ec63e07aSXin Li-}; 526*ec63e07aSXin Li- 527*ec63e07aSXin Li-/* -->> -->> -->> -->> 528*ec63e07aSXin Li- 529*ec63e07aSXin Li- TGA IMAGE FORMAT 530*ec63e07aSXin Li- 531*ec63e07aSXin Li- <<-- <<-- <<-- <<-- */ 532*ec63e07aSXin Li- 533*ec63e07aSXin Li-#ifdef INFORMATION_ONLY 534*ec63e07aSXin Li-/* TGA header definition. */ 535*ec63e07aSXin Li-struct tga_header { 536*ec63e07aSXin Li- unsigned char id_length; /* Image id field length */ 537*ec63e07aSXin Li- unsigned char colour_map_type; /* Colour map type */ 538*ec63e07aSXin Li- unsigned char image_type; /* Image type */ 539*ec63e07aSXin Li- /* 540*ec63e07aSXin Li- ** Colour map specification 541*ec63e07aSXin Li- */ 542*ec63e07aSXin Li- unsigned short colour_map_index; /* First entry index */ 543*ec63e07aSXin Li- unsigned short colour_map_length; /* Colour map length */ 544*ec63e07aSXin Li- unsigned char colour_map_entry_size; /* Colour map entry size */ 545*ec63e07aSXin Li- /* 546*ec63e07aSXin Li- ** Image specification 547*ec63e07aSXin Li- */ 548*ec63e07aSXin Li- unsigned short x_origin; /* x origin of image */ 549*ec63e07aSXin Li- unsigned short y_origin; /* u origin of image */ 550*ec63e07aSXin Li- unsigned short image_width; /* Image width */ 551*ec63e07aSXin Li- unsigned short image_height; /* Image height */ 552*ec63e07aSXin Li- unsigned char pixel_depth; /* Pixel depth */ 553*ec63e07aSXin Li- unsigned char image_desc; /* Image descriptor */ 554*ec63e07aSXin Li-}; 555*ec63e07aSXin Li-#endif /* INFORMATION_ONLY */ 556*ec63e07aSXin Li- 557*ec63e07aSXin Li-/* Returns a ushort from a little-endian serialized value */ 558*ec63e07aSXin Li-static unsigned short get_tga_ushort(const unsigned char *data) 559*ec63e07aSXin Li-{ 560*ec63e07aSXin Li- return (unsigned short)(data[0] | (data[1] << 8)); 561*ec63e07aSXin Li-} 562*ec63e07aSXin Li- 563*ec63e07aSXin Li-#define TGA_HEADER_SIZE 18 564*ec63e07aSXin Li- 565*ec63e07aSXin Li-static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel, 566*ec63e07aSXin Li- unsigned int *width, unsigned int *height, int *flip_image) 567*ec63e07aSXin Li-{ 568*ec63e07aSXin Li- int palette_size; 569*ec63e07aSXin Li- unsigned char tga[TGA_HEADER_SIZE]; 570*ec63e07aSXin Li- unsigned char id_len, /*cmap_type,*/ image_type; 571*ec63e07aSXin Li- unsigned char pixel_depth, image_desc; 572*ec63e07aSXin Li- unsigned short /*cmap_index,*/ cmap_len, cmap_entry_size; 573*ec63e07aSXin Li- unsigned short /*x_origin, y_origin,*/ image_w, image_h; 574*ec63e07aSXin Li- 575*ec63e07aSXin Li- if (!bits_per_pixel || !width || !height || !flip_image) { 576*ec63e07aSXin Li- return 0; 577*ec63e07aSXin Li- } 578*ec63e07aSXin Li- 579*ec63e07aSXin Li- if (fread(tga, TGA_HEADER_SIZE, 1, fp) != 1) { 580*ec63e07aSXin Li- fprintf(stderr, 581*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 582*ec63e07aSXin Li- return 0 ; 583*ec63e07aSXin Li- } 584*ec63e07aSXin Li- id_len = tga[0]; 585*ec63e07aSXin Li- /*cmap_type = tga[1];*/ 586*ec63e07aSXin Li- image_type = tga[2]; 587*ec63e07aSXin Li- /*cmap_index = get_tga_ushort(&tga[3]);*/ 588*ec63e07aSXin Li- cmap_len = get_tga_ushort(&tga[5]); 589*ec63e07aSXin Li- cmap_entry_size = tga[7]; 590*ec63e07aSXin Li- 591*ec63e07aSXin Li- 592*ec63e07aSXin Li-#if 0 593*ec63e07aSXin Li- x_origin = get_tga_ushort(&tga[8]); 594*ec63e07aSXin Li- y_origin = get_tga_ushort(&tga[10]); 595*ec63e07aSXin Li-#endif 596*ec63e07aSXin Li- image_w = get_tga_ushort(&tga[12]); 597*ec63e07aSXin Li- image_h = get_tga_ushort(&tga[14]); 598*ec63e07aSXin Li- pixel_depth = tga[16]; 599*ec63e07aSXin Li- image_desc = tga[17]; 600*ec63e07aSXin Li- 601*ec63e07aSXin Li- *bits_per_pixel = (unsigned int)pixel_depth; 602*ec63e07aSXin Li- *width = (unsigned int)image_w; 603*ec63e07aSXin Li- *height = (unsigned int)image_h; 604*ec63e07aSXin Li- 605*ec63e07aSXin Li- /* Ignore tga identifier, if present ... */ 606*ec63e07aSXin Li- if (id_len) { 607*ec63e07aSXin Li- unsigned char *id = (unsigned char *) malloc(id_len); 608*ec63e07aSXin Li- if (id == 0) { 609*ec63e07aSXin Li- fprintf(stderr, "tga_readheader: memory out\n"); 610*ec63e07aSXin Li- return 0; 611*ec63e07aSXin Li- } 612*ec63e07aSXin Li- if (!fread(id, id_len, 1, fp)) { 613*ec63e07aSXin Li- fprintf(stderr, 614*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 615*ec63e07aSXin Li- free(id); 616*ec63e07aSXin Li- return 0 ; 617*ec63e07aSXin Li- } 618*ec63e07aSXin Li- free(id); 619*ec63e07aSXin Li- } 620*ec63e07aSXin Li- 621*ec63e07aSXin Li- /* Test for compressed formats ... not yet supported ... 622*ec63e07aSXin Li- // Note :- 9 - RLE encoded palettized. 623*ec63e07aSXin Li- // 10 - RLE encoded RGB. */ 624*ec63e07aSXin Li- if (image_type > 8) { 625*ec63e07aSXin Li- fprintf(stderr, "Sorry, compressed tga files are not currently supported.\n"); 626*ec63e07aSXin Li- return 0 ; 627*ec63e07aSXin Li- } 628*ec63e07aSXin Li- 629*ec63e07aSXin Li- *flip_image = !(image_desc & 32); 630*ec63e07aSXin Li- 631*ec63e07aSXin Li- /* Palettized formats are not yet supported, skip over the palette, if present ... */ 632*ec63e07aSXin Li- palette_size = cmap_len * (cmap_entry_size / 8); 633*ec63e07aSXin Li- 634*ec63e07aSXin Li- if (palette_size > 0) { 635*ec63e07aSXin Li- fprintf(stderr, "File contains a palette - not yet supported."); 636*ec63e07aSXin Li- fseek(fp, palette_size, SEEK_CUR); 637*ec63e07aSXin Li- } 638*ec63e07aSXin Li+static int are_comps_similar(opj_image_t *image) { 639*ec63e07aSXin Li+ unsigned int i; 640*ec63e07aSXin Li+ for (i = 1; i < image->numcomps; i++) { 641*ec63e07aSXin Li+ if (image->comps[0].dx != image->comps[i].dx || 642*ec63e07aSXin Li+ image->comps[0].dy != image->comps[i].dy || 643*ec63e07aSXin Li+ (i <= 2 && (image->comps[0].prec != image->comps[i].prec || 644*ec63e07aSXin Li+ image->comps[0].sgnd != image->comps[i].sgnd))) { 645*ec63e07aSXin Li+ return OPJ_FALSE; 646*ec63e07aSXin Li+ } 647*ec63e07aSXin Li+ } 648*ec63e07aSXin Li+ return OPJ_TRUE; 649*ec63e07aSXin Li+} 650*ec63e07aSXin Li+ 651*ec63e07aSXin Li+int imagetopnm(opj_image_t *image, const char *outfile, int force_split) { 652*ec63e07aSXin Li+ int *red, *green, *blue, *alpha; 653*ec63e07aSXin Li+ int wr, hr, max; 654*ec63e07aSXin Li+ int i; 655*ec63e07aSXin Li+ unsigned int compno, ncomp; 656*ec63e07aSXin Li+ int adjustR, adjustG, adjustB, adjustA; 657*ec63e07aSXin Li+ int fails, two, want_gray, has_alpha, triple; 658*ec63e07aSXin Li+ int prec, v; 659*ec63e07aSXin Li+ FILE *fdest = NULL; 660*ec63e07aSXin Li+ const char *tmp = outfile; 661*ec63e07aSXin Li+ char *destname; 662*ec63e07aSXin Li+ 663*ec63e07aSXin Li+ alpha = NULL; 664*ec63e07aSXin Li+ 665*ec63e07aSXin Li+ if ((prec = (int)image->comps[0].prec) > 16) { 666*ec63e07aSXin Li+ fprintf(stderr, 667*ec63e07aSXin Li+ "%s:%d:imagetopnm\n\tprecision %d is larger than 16" 668*ec63e07aSXin Li+ "\n\t: refused.\n", 669*ec63e07aSXin Li+ __FILE__, __LINE__, prec); 670*ec63e07aSXin Li return 1; 671*ec63e07aSXin Li-} 672*ec63e07aSXin Li- 673*ec63e07aSXin Li-#ifdef OPJ_BIG_ENDIAN 674*ec63e07aSXin Li- 675*ec63e07aSXin Li-static INLINE OPJ_UINT16 swap16(OPJ_UINT16 x) 676*ec63e07aSXin Li-{ 677*ec63e07aSXin Li- return (OPJ_UINT16)(((x & 0x00ffU) << 8) | ((x & 0xff00U) >> 8)); 678*ec63e07aSXin Li-} 679*ec63e07aSXin Li- 680*ec63e07aSXin Li-#endif 681*ec63e07aSXin Li+ } 682*ec63e07aSXin Li 683*ec63e07aSXin Li-static int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height, 684*ec63e07aSXin Li- OPJ_BOOL flip_image) 685*ec63e07aSXin Li-{ 686*ec63e07aSXin Li- OPJ_UINT16 image_w, image_h, us0; 687*ec63e07aSXin Li- unsigned char uc0, image_type; 688*ec63e07aSXin Li- unsigned char pixel_depth, image_desc; 689*ec63e07aSXin Li- 690*ec63e07aSXin Li- if (!bits_per_pixel || !width || !height) { 691*ec63e07aSXin Li- return 0; 692*ec63e07aSXin Li- } 693*ec63e07aSXin Li- 694*ec63e07aSXin Li- pixel_depth = 0; 695*ec63e07aSXin Li- 696*ec63e07aSXin Li- if (bits_per_pixel < 256) { 697*ec63e07aSXin Li- pixel_depth = (unsigned char)bits_per_pixel; 698*ec63e07aSXin Li- } else { 699*ec63e07aSXin Li- fprintf(stderr, "ERROR: Wrong bits per pixel inside tga_header"); 700*ec63e07aSXin Li- return 0; 701*ec63e07aSXin Li- } 702*ec63e07aSXin Li- uc0 = 0; 703*ec63e07aSXin Li- 704*ec63e07aSXin Li- if (fwrite(&uc0, 1, 1, fp) != 1) { 705*ec63e07aSXin Li- goto fails; /* id_length */ 706*ec63e07aSXin Li- } 707*ec63e07aSXin Li- if (fwrite(&uc0, 1, 1, fp) != 1) { 708*ec63e07aSXin Li- goto fails; /* colour_map_type */ 709*ec63e07aSXin Li- } 710*ec63e07aSXin Li- 711*ec63e07aSXin Li- image_type = 2; /* Uncompressed. */ 712*ec63e07aSXin Li- if (fwrite(&image_type, 1, 1, fp) != 1) { 713*ec63e07aSXin Li- goto fails; 714*ec63e07aSXin Li- } 715*ec63e07aSXin Li- 716*ec63e07aSXin Li- us0 = 0; 717*ec63e07aSXin Li- if (fwrite(&us0, 2, 1, fp) != 1) { 718*ec63e07aSXin Li- goto fails; /* colour_map_index */ 719*ec63e07aSXin Li- } 720*ec63e07aSXin Li- if (fwrite(&us0, 2, 1, fp) != 1) { 721*ec63e07aSXin Li- goto fails; /* colour_map_length */ 722*ec63e07aSXin Li- } 723*ec63e07aSXin Li- if (fwrite(&uc0, 1, 1, fp) != 1) { 724*ec63e07aSXin Li- goto fails; /* colour_map_entry_size */ 725*ec63e07aSXin Li- } 726*ec63e07aSXin Li- 727*ec63e07aSXin Li- if (fwrite(&us0, 2, 1, fp) != 1) { 728*ec63e07aSXin Li- goto fails; /* x_origin */ 729*ec63e07aSXin Li- } 730*ec63e07aSXin Li- if (fwrite(&us0, 2, 1, fp) != 1) { 731*ec63e07aSXin Li- goto fails; /* y_origin */ 732*ec63e07aSXin Li- } 733*ec63e07aSXin Li- 734*ec63e07aSXin Li- image_w = (unsigned short)width; 735*ec63e07aSXin Li- image_h = (unsigned short) height; 736*ec63e07aSXin Li- 737*ec63e07aSXin Li-#ifndef OPJ_BIG_ENDIAN 738*ec63e07aSXin Li- if (fwrite(&image_w, 2, 1, fp) != 1) { 739*ec63e07aSXin Li- goto fails; 740*ec63e07aSXin Li- } 741*ec63e07aSXin Li- if (fwrite(&image_h, 2, 1, fp) != 1) { 742*ec63e07aSXin Li- goto fails; 743*ec63e07aSXin Li- } 744*ec63e07aSXin Li-#else 745*ec63e07aSXin Li- image_w = swap16(image_w); 746*ec63e07aSXin Li- image_h = swap16(image_h); 747*ec63e07aSXin Li- if (fwrite(&image_w, 2, 1, fp) != 1) { 748*ec63e07aSXin Li- goto fails; 749*ec63e07aSXin Li- } 750*ec63e07aSXin Li- if (fwrite(&image_h, 2, 1, fp) != 1) { 751*ec63e07aSXin Li- goto fails; 752*ec63e07aSXin Li- } 753*ec63e07aSXin Li-#endif 754*ec63e07aSXin Li- 755*ec63e07aSXin Li- if (fwrite(&pixel_depth, 1, 1, fp) != 1) { 756*ec63e07aSXin Li- goto fails; 757*ec63e07aSXin Li- } 758*ec63e07aSXin Li- 759*ec63e07aSXin Li- image_desc = 8; /* 8 bits per component. */ 760*ec63e07aSXin Li- 761*ec63e07aSXin Li- if (flip_image) { 762*ec63e07aSXin Li- image_desc |= 32; 763*ec63e07aSXin Li- } 764*ec63e07aSXin Li- if (fwrite(&image_desc, 1, 1, fp) != 1) { 765*ec63e07aSXin Li- goto fails; 766*ec63e07aSXin Li- } 767*ec63e07aSXin Li- 768*ec63e07aSXin Li- return 1; 769*ec63e07aSXin Li- 770*ec63e07aSXin Li-fails: 771*ec63e07aSXin Li- fputs("\nwrite_tgaheader: write ERROR\n", stderr); 772*ec63e07aSXin Li- return 0; 773*ec63e07aSXin Li-} 774*ec63e07aSXin Li- 775*ec63e07aSXin Li-opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) 776*ec63e07aSXin Li-{ 777*ec63e07aSXin Li- FILE *f; 778*ec63e07aSXin Li- opj_image_t *image; 779*ec63e07aSXin Li- unsigned int image_width, image_height, pixel_bit_depth; 780*ec63e07aSXin Li- unsigned int x, y; 781*ec63e07aSXin Li- int flip_image = 0; 782*ec63e07aSXin Li- opj_image_cmptparm_t cmptparm[4]; /* maximum 4 components */ 783*ec63e07aSXin Li- int numcomps; 784*ec63e07aSXin Li- OPJ_COLOR_SPACE color_space; 785*ec63e07aSXin Li- OPJ_BOOL mono ; 786*ec63e07aSXin Li- OPJ_BOOL save_alpha; 787*ec63e07aSXin Li- int subsampling_dx, subsampling_dy; 788*ec63e07aSXin Li- int i; 789*ec63e07aSXin Li- 790*ec63e07aSXin Li- f = fopen(filename, "rb"); 791*ec63e07aSXin Li- if (!f) { 792*ec63e07aSXin Li- fprintf(stderr, "Failed to open %s for reading !!\n", filename); 793*ec63e07aSXin Li- return 0; 794*ec63e07aSXin Li- } 795*ec63e07aSXin Li- 796*ec63e07aSXin Li- if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, 797*ec63e07aSXin Li- &flip_image)) { 798*ec63e07aSXin Li- fclose(f); 799*ec63e07aSXin Li- return NULL; 800*ec63e07aSXin Li- } 801*ec63e07aSXin Li- 802*ec63e07aSXin Li- /* We currently only support 24 & 32 bit tga's ... */ 803*ec63e07aSXin Li- if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32))) { 804*ec63e07aSXin Li- fclose(f); 805*ec63e07aSXin Li- return NULL; 806*ec63e07aSXin Li- } 807*ec63e07aSXin Li- 808*ec63e07aSXin Li- /* initialize image components */ 809*ec63e07aSXin Li- memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); 810*ec63e07aSXin Li- 811*ec63e07aSXin Li- mono = (pixel_bit_depth == 8) || 812*ec63e07aSXin Li- (pixel_bit_depth == 16); /* Mono with & without alpha. */ 813*ec63e07aSXin Li- save_alpha = (pixel_bit_depth == 16) || 814*ec63e07aSXin Li- (pixel_bit_depth == 32); /* Mono with alpha, or RGB with alpha */ 815*ec63e07aSXin Li- 816*ec63e07aSXin Li- if (mono) { 817*ec63e07aSXin Li- color_space = OPJ_CLRSPC_GRAY; 818*ec63e07aSXin Li- numcomps = save_alpha ? 2 : 1; 819*ec63e07aSXin Li- } else { 820*ec63e07aSXin Li- numcomps = save_alpha ? 4 : 3; 821*ec63e07aSXin Li- color_space = OPJ_CLRSPC_SRGB; 822*ec63e07aSXin Li- } 823*ec63e07aSXin Li- 824*ec63e07aSXin Li- /* If the declared file size is > 10 MB, check that the file is big */ 825*ec63e07aSXin Li- /* enough to avoid excessive memory allocations */ 826*ec63e07aSXin Li- if (image_height != 0 && 827*ec63e07aSXin Li- image_width > 10000000U / image_height / (OPJ_UINT32)numcomps) { 828*ec63e07aSXin Li- char ch; 829*ec63e07aSXin Li- OPJ_UINT64 expected_file_size = 830*ec63e07aSXin Li- (OPJ_UINT64)image_width * image_height * (OPJ_UINT32)numcomps; 831*ec63e07aSXin Li- long curpos = ftell(f); 832*ec63e07aSXin Li- if (expected_file_size > (OPJ_UINT64)INT_MAX) { 833*ec63e07aSXin Li- expected_file_size = (OPJ_UINT64)INT_MAX; 834*ec63e07aSXin Li- } 835*ec63e07aSXin Li- fseek(f, (long)expected_file_size - 1, SEEK_SET); 836*ec63e07aSXin Li- if (fread(&ch, 1, 1, f) != 1) { 837*ec63e07aSXin Li- fclose(f); 838*ec63e07aSXin Li- return NULL; 839*ec63e07aSXin Li- } 840*ec63e07aSXin Li- fseek(f, curpos, SEEK_SET); 841*ec63e07aSXin Li- } 842*ec63e07aSXin Li- 843*ec63e07aSXin Li- subsampling_dx = parameters->subsampling_dx; 844*ec63e07aSXin Li- subsampling_dy = parameters->subsampling_dy; 845*ec63e07aSXin Li- 846*ec63e07aSXin Li- for (i = 0; i < numcomps; i++) { 847*ec63e07aSXin Li- cmptparm[i].prec = 8; 848*ec63e07aSXin Li- cmptparm[i].bpp = 8; 849*ec63e07aSXin Li- cmptparm[i].sgnd = 0; 850*ec63e07aSXin Li- cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; 851*ec63e07aSXin Li- cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; 852*ec63e07aSXin Li- cmptparm[i].w = image_width; 853*ec63e07aSXin Li- cmptparm[i].h = image_height; 854*ec63e07aSXin Li- } 855*ec63e07aSXin Li- 856*ec63e07aSXin Li- /* create the image */ 857*ec63e07aSXin Li- image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); 858*ec63e07aSXin Li- 859*ec63e07aSXin Li- if (!image) { 860*ec63e07aSXin Li- fclose(f); 861*ec63e07aSXin Li- return NULL; 862*ec63e07aSXin Li- } 863*ec63e07aSXin Li- 864*ec63e07aSXin Li- 865*ec63e07aSXin Li- /* set image offset and reference grid */ 866*ec63e07aSXin Li- image->x0 = (OPJ_UINT32)parameters->image_offset_x0; 867*ec63e07aSXin Li- image->y0 = (OPJ_UINT32)parameters->image_offset_y0; 868*ec63e07aSXin Li- image->x1 = !image->x0 ? (OPJ_UINT32)(image_width - 1) * 869*ec63e07aSXin Li- (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(image_width - 1) * 870*ec63e07aSXin Li- (OPJ_UINT32)subsampling_dx + 1; 871*ec63e07aSXin Li- image->y1 = !image->y0 ? (OPJ_UINT32)(image_height - 1) * 872*ec63e07aSXin Li- (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(image_height - 1) * 873*ec63e07aSXin Li- (OPJ_UINT32)subsampling_dy + 1; 874*ec63e07aSXin Li- 875*ec63e07aSXin Li- /* set image data */ 876*ec63e07aSXin Li- for (y = 0; y < image_height; y++) { 877*ec63e07aSXin Li- int index; 878*ec63e07aSXin Li- 879*ec63e07aSXin Li- if (flip_image) { 880*ec63e07aSXin Li- index = (int)((image_height - y - 1) * image_width); 881*ec63e07aSXin Li- } else { 882*ec63e07aSXin Li- index = (int)(y * image_width); 883*ec63e07aSXin Li- } 884*ec63e07aSXin Li- 885*ec63e07aSXin Li- if (numcomps == 3) { 886*ec63e07aSXin Li- for (x = 0; x < image_width; x++) { 887*ec63e07aSXin Li- unsigned char r, g, b; 888*ec63e07aSXin Li- 889*ec63e07aSXin Li- if (!fread(&b, 1, 1, f)) { 890*ec63e07aSXin Li- fprintf(stderr, 891*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 892*ec63e07aSXin Li- opj_image_destroy(image); 893*ec63e07aSXin Li- fclose(f); 894*ec63e07aSXin Li- return NULL; 895*ec63e07aSXin Li- } 896*ec63e07aSXin Li- if (!fread(&g, 1, 1, f)) { 897*ec63e07aSXin Li- fprintf(stderr, 898*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 899*ec63e07aSXin Li- opj_image_destroy(image); 900*ec63e07aSXin Li- fclose(f); 901*ec63e07aSXin Li- return NULL; 902*ec63e07aSXin Li- } 903*ec63e07aSXin Li- if (!fread(&r, 1, 1, f)) { 904*ec63e07aSXin Li- fprintf(stderr, 905*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 906*ec63e07aSXin Li- opj_image_destroy(image); 907*ec63e07aSXin Li- fclose(f); 908*ec63e07aSXin Li- return NULL; 909*ec63e07aSXin Li- } 910*ec63e07aSXin Li- 911*ec63e07aSXin Li- image->comps[0].data[index] = r; 912*ec63e07aSXin Li- image->comps[1].data[index] = g; 913*ec63e07aSXin Li- image->comps[2].data[index] = b; 914*ec63e07aSXin Li- index++; 915*ec63e07aSXin Li- } 916*ec63e07aSXin Li- } else if (numcomps == 4) { 917*ec63e07aSXin Li- for (x = 0; x < image_width; x++) { 918*ec63e07aSXin Li- unsigned char r, g, b, a; 919*ec63e07aSXin Li- if (!fread(&b, 1, 1, f)) { 920*ec63e07aSXin Li- fprintf(stderr, 921*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 922*ec63e07aSXin Li- opj_image_destroy(image); 923*ec63e07aSXin Li- fclose(f); 924*ec63e07aSXin Li- return NULL; 925*ec63e07aSXin Li- } 926*ec63e07aSXin Li- if (!fread(&g, 1, 1, f)) { 927*ec63e07aSXin Li- fprintf(stderr, 928*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 929*ec63e07aSXin Li- opj_image_destroy(image); 930*ec63e07aSXin Li- fclose(f); 931*ec63e07aSXin Li- return NULL; 932*ec63e07aSXin Li- } 933*ec63e07aSXin Li- if (!fread(&r, 1, 1, f)) { 934*ec63e07aSXin Li- fprintf(stderr, 935*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 936*ec63e07aSXin Li- opj_image_destroy(image); 937*ec63e07aSXin Li- fclose(f); 938*ec63e07aSXin Li- return NULL; 939*ec63e07aSXin Li- } 940*ec63e07aSXin Li- if (!fread(&a, 1, 1, f)) { 941*ec63e07aSXin Li- fprintf(stderr, 942*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 943*ec63e07aSXin Li- opj_image_destroy(image); 944*ec63e07aSXin Li- fclose(f); 945*ec63e07aSXin Li- return NULL; 946*ec63e07aSXin Li- } 947*ec63e07aSXin Li- 948*ec63e07aSXin Li- image->comps[0].data[index] = r; 949*ec63e07aSXin Li- image->comps[1].data[index] = g; 950*ec63e07aSXin Li- image->comps[2].data[index] = b; 951*ec63e07aSXin Li- image->comps[3].data[index] = a; 952*ec63e07aSXin Li- index++; 953*ec63e07aSXin Li- } 954*ec63e07aSXin Li- } else { 955*ec63e07aSXin Li- fprintf(stderr, "Currently unsupported bit depth : %s\n", filename); 956*ec63e07aSXin Li- } 957*ec63e07aSXin Li- } 958*ec63e07aSXin Li- fclose(f); 959*ec63e07aSXin Li- return image; 960*ec63e07aSXin Li-} 961*ec63e07aSXin Li- 962*ec63e07aSXin Li-int imagetotga(opj_image_t * image, const char *outfile) 963*ec63e07aSXin Li-{ 964*ec63e07aSXin Li- int width, height, bpp, x, y; 965*ec63e07aSXin Li- OPJ_BOOL write_alpha; 966*ec63e07aSXin Li- unsigned int i; 967*ec63e07aSXin Li- int adjustR, adjustG = 0, adjustB = 0, fails; 968*ec63e07aSXin Li- unsigned int alpha_channel; 969*ec63e07aSXin Li- float r, g, b, a; 970*ec63e07aSXin Li- unsigned char value; 971*ec63e07aSXin Li- float scale; 972*ec63e07aSXin Li- FILE *fdest; 973*ec63e07aSXin Li- size_t res; 974*ec63e07aSXin Li- fails = 1; 975*ec63e07aSXin Li+ two = has_alpha = 0; 976*ec63e07aSXin Li+ fails = 1; 977*ec63e07aSXin Li+ ncomp = image->numcomps; 978*ec63e07aSXin Li+ 979*ec63e07aSXin Li+ while (*tmp) { 980*ec63e07aSXin Li+ ++tmp; 981*ec63e07aSXin Li+ } 982*ec63e07aSXin Li+ tmp -= 2; 983*ec63e07aSXin Li+ want_gray = (*tmp == 'g' || *tmp == 'G'); 984*ec63e07aSXin Li+ ncomp = image->numcomps; 985*ec63e07aSXin Li+ 986*ec63e07aSXin Li+ if (want_gray) { 987*ec63e07aSXin Li+ ncomp = 1; 988*ec63e07aSXin Li+ } 989*ec63e07aSXin Li 990*ec63e07aSXin Li+ if ((force_split == 0) && ncomp >= 2 && are_comps_similar(image)) { 991*ec63e07aSXin Li fdest = fopen(outfile, "wb"); 992*ec63e07aSXin Li+ 993*ec63e07aSXin Li if (!fdest) { 994*ec63e07aSXin Li- fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); 995*ec63e07aSXin Li- return 1; 996*ec63e07aSXin Li+ fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); 997*ec63e07aSXin Li+ return fails; 998*ec63e07aSXin Li } 999*ec63e07aSXin Li- 1000*ec63e07aSXin Li- for (i = 0; i < image->numcomps - 1; i++) { 1001*ec63e07aSXin Li- if ((image->comps[0].dx != image->comps[i + 1].dx) 1002*ec63e07aSXin Li- || (image->comps[0].dy != image->comps[i + 1].dy) 1003*ec63e07aSXin Li- || (image->comps[0].prec != image->comps[i + 1].prec) 1004*ec63e07aSXin Li- || (image->comps[0].sgnd != image->comps[i + 1].sgnd)) { 1005*ec63e07aSXin Li- fclose(fdest); 1006*ec63e07aSXin Li- fprintf(stderr, 1007*ec63e07aSXin Li- "Unable to create a tga file with such J2K image charateristics.\n"); 1008*ec63e07aSXin Li- return 1; 1009*ec63e07aSXin Li- } 1010*ec63e07aSXin Li+ two = (prec > 8); 1011*ec63e07aSXin Li+ triple = (ncomp > 2); 1012*ec63e07aSXin Li+ wr = (int)image->comps[0].w; 1013*ec63e07aSXin Li+ hr = (int)image->comps[0].h; 1014*ec63e07aSXin Li+ max = (1 << prec) - 1; 1015*ec63e07aSXin Li+ has_alpha = (ncomp == 4 || ncomp == 2); 1016*ec63e07aSXin Li+ 1017*ec63e07aSXin Li+ red = image->comps[0].data; 1018*ec63e07aSXin Li+ if (red == NULL) { 1019*ec63e07aSXin Li+ fprintf(stderr, "imagetopnm: planes[%d] == NULL.\n", 0); 1020*ec63e07aSXin Li+ fprintf(stderr, "\tAborting\n"); 1021*ec63e07aSXin Li+ fclose(fdest); 1022*ec63e07aSXin Li+ return fails; 1023*ec63e07aSXin Li+ } 1024*ec63e07aSXin Li+ 1025*ec63e07aSXin Li+ if (triple) { 1026*ec63e07aSXin Li+ green = image->comps[1].data; 1027*ec63e07aSXin Li+ blue = image->comps[2].data; 1028*ec63e07aSXin Li+ for (i = 1; i <= 2; i++) { 1029*ec63e07aSXin Li+ if (image->comps[i].data == NULL) { 1030*ec63e07aSXin Li+ fprintf(stderr, "imagetopnm: planes[%d] == NULL.\n", i); 1031*ec63e07aSXin Li+ fprintf(stderr, "\tAborting\n"); 1032*ec63e07aSXin Li+ fclose(fdest); 1033*ec63e07aSXin Li+ return fails; 1034*ec63e07aSXin Li+ } 1035*ec63e07aSXin Li+ } 1036*ec63e07aSXin Li+ } else { 1037*ec63e07aSXin Li+ green = blue = NULL; 1038*ec63e07aSXin Li+ } 1039*ec63e07aSXin Li+ 1040*ec63e07aSXin Li+ if (has_alpha) { 1041*ec63e07aSXin Li+ const char *tt = (triple ? "RGB_ALPHA" : "GRAYSCALE_ALPHA"); 1042*ec63e07aSXin Li+ 1043*ec63e07aSXin Li+ fprintf(fdest, 1044*ec63e07aSXin Li+ "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %u\n" 1045*ec63e07aSXin Li+ "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", 1046*ec63e07aSXin Li+ opj_version(), wr, hr, ncomp, max, tt); 1047*ec63e07aSXin Li+ alpha = image->comps[ncomp - 1].data; 1048*ec63e07aSXin Li+ adjustA = (image->comps[ncomp - 1].sgnd 1049*ec63e07aSXin Li+ ? 1 << (image->comps[ncomp - 1].prec - 1) 1050*ec63e07aSXin Li+ : 0); 1051*ec63e07aSXin Li+ } else { 1052*ec63e07aSXin Li+ fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n", opj_version(), wr, hr, 1053*ec63e07aSXin Li+ max); 1054*ec63e07aSXin Li+ adjustA = 0; 1055*ec63e07aSXin Li } 1056*ec63e07aSXin Li- 1057*ec63e07aSXin Li- width = (int)image->comps[0].w; 1058*ec63e07aSXin Li- height = (int)image->comps[0].h; 1059*ec63e07aSXin Li- 1060*ec63e07aSXin Li- /* Mono with alpha, or RGB with alpha. */ 1061*ec63e07aSXin Li- write_alpha = (image->numcomps == 2) || (image->numcomps == 4); 1062*ec63e07aSXin Li- 1063*ec63e07aSXin Li- /* Write TGA header */ 1064*ec63e07aSXin Li- bpp = write_alpha ? 32 : 24; 1065*ec63e07aSXin Li- 1066*ec63e07aSXin Li- if (!tga_writeheader(fdest, bpp, width, height, OPJ_TRUE)) { 1067*ec63e07aSXin Li- goto fin; 1068*ec63e07aSXin Li- } 1069*ec63e07aSXin Li- 1070*ec63e07aSXin Li- alpha_channel = image->numcomps - 1; 1071*ec63e07aSXin Li- 1072*ec63e07aSXin Li- scale = 255.0f / (float)((1 << image->comps[0].prec) - 1); 1073*ec63e07aSXin Li- 1074*ec63e07aSXin Li adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); 1075*ec63e07aSXin Li- if (image->numcomps >= 3) { 1076*ec63e07aSXin Li- adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); 1077*ec63e07aSXin Li- adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); 1078*ec63e07aSXin Li- } 1079*ec63e07aSXin Li- 1080*ec63e07aSXin Li- for (y = 0; y < height; y++) { 1081*ec63e07aSXin Li- unsigned int index = (unsigned int)(y * width); 1082*ec63e07aSXin Li- 1083*ec63e07aSXin Li- for (x = 0; x < width; x++, index++) { 1084*ec63e07aSXin Li- r = (float)(image->comps[0].data[index] + adjustR); 1085*ec63e07aSXin Li 1086*ec63e07aSXin Li- if (image->numcomps > 2) { 1087*ec63e07aSXin Li- g = (float)(image->comps[1].data[index] + adjustG); 1088*ec63e07aSXin Li- b = (float)(image->comps[2].data[index] + adjustB); 1089*ec63e07aSXin Li- } else { 1090*ec63e07aSXin Li- /* Greyscale ... */ 1091*ec63e07aSXin Li- g = r; 1092*ec63e07aSXin Li- b = r; 1093*ec63e07aSXin Li- } 1094*ec63e07aSXin Li- 1095*ec63e07aSXin Li- /* TGA format writes BGR ... */ 1096*ec63e07aSXin Li- if (b > 255.) { 1097*ec63e07aSXin Li- b = 255.; 1098*ec63e07aSXin Li- } else if (b < 0.) { 1099*ec63e07aSXin Li- b = 0.; 1100*ec63e07aSXin Li- } 1101*ec63e07aSXin Li- value = (unsigned char)(b * scale); 1102*ec63e07aSXin Li- res = fwrite(&value, 1, 1, fdest); 1103*ec63e07aSXin Li- 1104*ec63e07aSXin Li- if (res < 1) { 1105*ec63e07aSXin Li- fprintf(stderr, "failed to write 1 byte for %s\n", outfile); 1106*ec63e07aSXin Li- goto fin; 1107*ec63e07aSXin Li- } 1108*ec63e07aSXin Li- if (g > 255.) { 1109*ec63e07aSXin Li- g = 255.; 1110*ec63e07aSXin Li- } else if (g < 0.) { 1111*ec63e07aSXin Li- g = 0.; 1112*ec63e07aSXin Li- } 1113*ec63e07aSXin Li- value = (unsigned char)(g * scale); 1114*ec63e07aSXin Li- res = fwrite(&value, 1, 1, fdest); 1115*ec63e07aSXin Li- 1116*ec63e07aSXin Li- if (res < 1) { 1117*ec63e07aSXin Li- fprintf(stderr, "failed to write 1 byte for %s\n", outfile); 1118*ec63e07aSXin Li- goto fin; 1119*ec63e07aSXin Li- } 1120*ec63e07aSXin Li- if (r > 255.) { 1121*ec63e07aSXin Li- r = 255.; 1122*ec63e07aSXin Li- } else if (r < 0.) { 1123*ec63e07aSXin Li- r = 0.; 1124*ec63e07aSXin Li- } 1125*ec63e07aSXin Li- value = (unsigned char)(r * scale); 1126*ec63e07aSXin Li- res = fwrite(&value, 1, 1, fdest); 1127*ec63e07aSXin Li- 1128*ec63e07aSXin Li- if (res < 1) { 1129*ec63e07aSXin Li- fprintf(stderr, "failed to write 1 byte for %s\n", outfile); 1130*ec63e07aSXin Li- goto fin; 1131*ec63e07aSXin Li- } 1132*ec63e07aSXin Li- 1133*ec63e07aSXin Li- if (write_alpha) { 1134*ec63e07aSXin Li- a = (float)(image->comps[alpha_channel].data[index]); 1135*ec63e07aSXin Li- if (a > 255.) { 1136*ec63e07aSXin Li- a = 255.; 1137*ec63e07aSXin Li- } else if (a < 0.) { 1138*ec63e07aSXin Li- a = 0.; 1139*ec63e07aSXin Li- } 1140*ec63e07aSXin Li- value = (unsigned char)(a * scale); 1141*ec63e07aSXin Li- res = fwrite(&value, 1, 1, fdest); 1142*ec63e07aSXin Li- 1143*ec63e07aSXin Li- if (res < 1) { 1144*ec63e07aSXin Li- fprintf(stderr, "failed to write 1 byte for %s\n", outfile); 1145*ec63e07aSXin Li- goto fin; 1146*ec63e07aSXin Li- } 1147*ec63e07aSXin Li- } 1148*ec63e07aSXin Li- } 1149*ec63e07aSXin Li- } 1150*ec63e07aSXin Li- fails = 0; 1151*ec63e07aSXin Li-fin: 1152*ec63e07aSXin Li- fclose(fdest); 1153*ec63e07aSXin Li- 1154*ec63e07aSXin Li- return fails; 1155*ec63e07aSXin Li-} 1156*ec63e07aSXin Li- 1157*ec63e07aSXin Li-/* -->> -->> -->> -->> 1158*ec63e07aSXin Li- 1159*ec63e07aSXin Li-PGX IMAGE FORMAT 1160*ec63e07aSXin Li- 1161*ec63e07aSXin Li-<<-- <<-- <<-- <<-- */ 1162*ec63e07aSXin Li- 1163*ec63e07aSXin Li- 1164*ec63e07aSXin Li-static unsigned char readuchar(FILE * f) 1165*ec63e07aSXin Li-{ 1166*ec63e07aSXin Li- unsigned char c1; 1167*ec63e07aSXin Li- if (!fread(&c1, 1, 1, f)) { 1168*ec63e07aSXin Li- fprintf(stderr, 1169*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 1170*ec63e07aSXin Li- return 0; 1171*ec63e07aSXin Li- } 1172*ec63e07aSXin Li- return c1; 1173*ec63e07aSXin Li-} 1174*ec63e07aSXin Li- 1175*ec63e07aSXin Li-static unsigned short readushort(FILE * f, int bigendian) 1176*ec63e07aSXin Li-{ 1177*ec63e07aSXin Li- unsigned char c1, c2; 1178*ec63e07aSXin Li- if (!fread(&c1, 1, 1, f)) { 1179*ec63e07aSXin Li- fprintf(stderr, 1180*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 1181*ec63e07aSXin Li- return 0; 1182*ec63e07aSXin Li- } 1183*ec63e07aSXin Li- if (!fread(&c2, 1, 1, f)) { 1184*ec63e07aSXin Li- fprintf(stderr, 1185*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 1186*ec63e07aSXin Li- return 0; 1187*ec63e07aSXin Li- } 1188*ec63e07aSXin Li- if (bigendian) { 1189*ec63e07aSXin Li- return (unsigned short)((c1 << 8) + c2); 1190*ec63e07aSXin Li- } else { 1191*ec63e07aSXin Li- return (unsigned short)((c2 << 8) + c1); 1192*ec63e07aSXin Li- } 1193*ec63e07aSXin Li-} 1194*ec63e07aSXin Li- 1195*ec63e07aSXin Li-static unsigned int readuint(FILE * f, int bigendian) 1196*ec63e07aSXin Li-{ 1197*ec63e07aSXin Li- unsigned char c1, c2, c3, c4; 1198*ec63e07aSXin Li- if (!fread(&c1, 1, 1, f)) { 1199*ec63e07aSXin Li- fprintf(stderr, 1200*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 1201*ec63e07aSXin Li- return 0; 1202*ec63e07aSXin Li- } 1203*ec63e07aSXin Li- if (!fread(&c2, 1, 1, f)) { 1204*ec63e07aSXin Li- fprintf(stderr, 1205*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 1206*ec63e07aSXin Li- return 0; 1207*ec63e07aSXin Li- } 1208*ec63e07aSXin Li- if (!fread(&c3, 1, 1, f)) { 1209*ec63e07aSXin Li- fprintf(stderr, 1210*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 1211*ec63e07aSXin Li- return 0; 1212*ec63e07aSXin Li- } 1213*ec63e07aSXin Li- if (!fread(&c4, 1, 1, f)) { 1214*ec63e07aSXin Li- fprintf(stderr, 1215*ec63e07aSXin Li- "\nError: fread return a number of element different from the expected.\n"); 1216*ec63e07aSXin Li- return 0; 1217*ec63e07aSXin Li- } 1218*ec63e07aSXin Li- if (bigendian) { 1219*ec63e07aSXin Li- return (unsigned int)(c1 << 24) + (unsigned int)(c2 << 16) + (unsigned int)( 1220*ec63e07aSXin Li- c3 << 8) + c4; 1221*ec63e07aSXin Li+ if (triple) { 1222*ec63e07aSXin Li+ adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); 1223*ec63e07aSXin Li+ adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); 1224*ec63e07aSXin Li } else { 1225*ec63e07aSXin Li- return (unsigned int)(c4 << 24) + (unsigned int)(c3 << 16) + (unsigned int)( 1226*ec63e07aSXin Li- c2 << 8) + c1; 1227*ec63e07aSXin Li- } 1228*ec63e07aSXin Li-} 1229*ec63e07aSXin Li- 1230*ec63e07aSXin Li-opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) 1231*ec63e07aSXin Li-{ 1232*ec63e07aSXin Li- FILE *f = NULL; 1233*ec63e07aSXin Li- int w, h, prec; 1234*ec63e07aSXin Li- int i, numcomps, max; 1235*ec63e07aSXin Li- OPJ_COLOR_SPACE color_space; 1236*ec63e07aSXin Li- opj_image_cmptparm_t cmptparm; /* maximum of 1 component */ 1237*ec63e07aSXin Li- opj_image_t * image = NULL; 1238*ec63e07aSXin Li- int adjustS, ushift, dshift, force8; 1239*ec63e07aSXin Li- OPJ_UINT64 expected_file_size; 1240*ec63e07aSXin Li- 1241*ec63e07aSXin Li- char endian1, endian2, sign; 1242*ec63e07aSXin Li- char signtmp[32]; 1243*ec63e07aSXin Li- 1244*ec63e07aSXin Li- char temp[32]; 1245*ec63e07aSXin Li- int bigendian; 1246*ec63e07aSXin Li- opj_image_comp_t *comp = NULL; 1247*ec63e07aSXin Li- 1248*ec63e07aSXin Li- numcomps = 1; 1249*ec63e07aSXin Li- color_space = OPJ_CLRSPC_GRAY; 1250*ec63e07aSXin Li- 1251*ec63e07aSXin Li- memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t)); 1252*ec63e07aSXin Li- 1253*ec63e07aSXin Li- max = 0; 1254*ec63e07aSXin Li- 1255*ec63e07aSXin Li- f = fopen(filename, "rb"); 1256*ec63e07aSXin Li- if (!f) { 1257*ec63e07aSXin Li- fprintf(stderr, "Failed to open %s for reading !\n", filename); 1258*ec63e07aSXin Li- return NULL; 1259*ec63e07aSXin Li+ adjustG = adjustB = 0; 1260*ec63e07aSXin Li } 1261*ec63e07aSXin Li 1262*ec63e07aSXin Li- fseek(f, 0, SEEK_SET); 1263*ec63e07aSXin Li- if (fscanf(f, "PG%31[ \t]%c%c%31[ \t+-]%d%31[ \t]%d%31[ \t]%d", temp, &endian1, 1264*ec63e07aSXin Li- &endian2, signtmp, &prec, temp, &w, temp, &h) != 9) { 1265*ec63e07aSXin Li- fclose(f); 1266*ec63e07aSXin Li- fprintf(stderr, 1267*ec63e07aSXin Li- "ERROR: Failed to read the right number of element from the fscanf() function!\n"); 1268*ec63e07aSXin Li- return NULL; 1269*ec63e07aSXin Li- } 1270*ec63e07aSXin Li- 1271*ec63e07aSXin Li- i = 0; 1272*ec63e07aSXin Li- sign = '+'; 1273*ec63e07aSXin Li- while (signtmp[i] != '\0') { 1274*ec63e07aSXin Li- if (signtmp[i] == '-') { 1275*ec63e07aSXin Li- sign = '-'; 1276*ec63e07aSXin Li+ for (i = 0; i < wr * hr; ++i) { 1277*ec63e07aSXin Li+ if (two) { 1278*ec63e07aSXin Li+ v = *red + adjustR; 1279*ec63e07aSXin Li+ ++red; 1280*ec63e07aSXin Li+ if (v > 65535) { 1281*ec63e07aSXin Li+ v = 65535; 1282*ec63e07aSXin Li+ } else if (v < 0) { 1283*ec63e07aSXin Li+ v = 0; 1284*ec63e07aSXin Li } 1285*ec63e07aSXin Li- i++; 1286*ec63e07aSXin Li- } 1287*ec63e07aSXin Li 1288*ec63e07aSXin Li- fgetc(f); 1289*ec63e07aSXin Li- if (endian1 == 'M' && endian2 == 'L') { 1290*ec63e07aSXin Li- bigendian = 1; 1291*ec63e07aSXin Li- } else if (endian2 == 'M' && endian1 == 'L') { 1292*ec63e07aSXin Li- bigendian = 0; 1293*ec63e07aSXin Li- } else { 1294*ec63e07aSXin Li- fclose(f); 1295*ec63e07aSXin Li- fprintf(stderr, "Bad pgx header, please check input file\n"); 1296*ec63e07aSXin Li- return NULL; 1297*ec63e07aSXin Li- } 1298*ec63e07aSXin Li- 1299*ec63e07aSXin Li- if (w < 1 || h < 1 || prec < 1 || prec > 31) { 1300*ec63e07aSXin Li- fclose(f); 1301*ec63e07aSXin Li- fprintf(stderr, "Bad pgx header, please check input file\n"); 1302*ec63e07aSXin Li- return NULL; 1303*ec63e07aSXin Li- } 1304*ec63e07aSXin Li- 1305*ec63e07aSXin Li- expected_file_size = 1306*ec63e07aSXin Li- (OPJ_UINT64)w * (OPJ_UINT64)h * (prec > 16 ? 4 : prec > 8 ? 2 : 1); 1307*ec63e07aSXin Li- if (expected_file_size > 10000000U) { 1308*ec63e07aSXin Li- char ch; 1309*ec63e07aSXin Li- long curpos = ftell(f); 1310*ec63e07aSXin Li- if (expected_file_size > (OPJ_UINT64)INT_MAX) { 1311*ec63e07aSXin Li- expected_file_size = (OPJ_UINT64)INT_MAX; 1312*ec63e07aSXin Li- } 1313*ec63e07aSXin Li- fseek(f, (long)expected_file_size - 1, SEEK_SET); 1314*ec63e07aSXin Li- if (fread(&ch, 1, 1, f) != 1) { 1315*ec63e07aSXin Li- fprintf(stderr, "File too short\n"); 1316*ec63e07aSXin Li- fclose(f); 1317*ec63e07aSXin Li- return NULL; 1318*ec63e07aSXin Li- } 1319*ec63e07aSXin Li- fseek(f, curpos, SEEK_SET); 1320*ec63e07aSXin Li- } 1321*ec63e07aSXin Li- 1322*ec63e07aSXin Li- /* initialize image component */ 1323*ec63e07aSXin Li- 1324*ec63e07aSXin Li- cmptparm.x0 = (OPJ_UINT32)parameters->image_offset_x0; 1325*ec63e07aSXin Li- cmptparm.y0 = (OPJ_UINT32)parameters->image_offset_y0; 1326*ec63e07aSXin Li- cmptparm.w = !cmptparm.x0 ? (OPJ_UINT32)((w - 1) * parameters->subsampling_dx + 1327*ec63e07aSXin Li- 1) : cmptparm.x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)parameters->subsampling_dx 1328*ec63e07aSXin Li- + 1; 1329*ec63e07aSXin Li- cmptparm.h = !cmptparm.y0 ? (OPJ_UINT32)((h - 1) * parameters->subsampling_dy + 1330*ec63e07aSXin Li- 1) : cmptparm.y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)parameters->subsampling_dy 1331*ec63e07aSXin Li- + 1; 1332*ec63e07aSXin Li- 1333*ec63e07aSXin Li- if (sign == '-') { 1334*ec63e07aSXin Li- cmptparm.sgnd = 1; 1335*ec63e07aSXin Li- } else { 1336*ec63e07aSXin Li- cmptparm.sgnd = 0; 1337*ec63e07aSXin Li- } 1338*ec63e07aSXin Li- if (prec < 8) { 1339*ec63e07aSXin Li- force8 = 1; 1340*ec63e07aSXin Li- ushift = 8 - prec; 1341*ec63e07aSXin Li- dshift = prec - ushift; 1342*ec63e07aSXin Li- if (cmptparm.sgnd) { 1343*ec63e07aSXin Li- adjustS = (1 << (prec - 1)); 1344*ec63e07aSXin Li- } else { 1345*ec63e07aSXin Li- adjustS = 0; 1346*ec63e07aSXin Li- } 1347*ec63e07aSXin Li- cmptparm.sgnd = 0; 1348*ec63e07aSXin Li- prec = 8; 1349*ec63e07aSXin Li- } else { 1350*ec63e07aSXin Li- ushift = dshift = force8 = adjustS = 0; 1351*ec63e07aSXin Li- } 1352*ec63e07aSXin Li- 1353*ec63e07aSXin Li- cmptparm.prec = (OPJ_UINT32)prec; 1354*ec63e07aSXin Li- cmptparm.bpp = (OPJ_UINT32)prec; 1355*ec63e07aSXin Li- cmptparm.dx = (OPJ_UINT32)parameters->subsampling_dx; 1356*ec63e07aSXin Li- cmptparm.dy = (OPJ_UINT32)parameters->subsampling_dy; 1357*ec63e07aSXin Li- 1358*ec63e07aSXin Li- /* create the image */ 1359*ec63e07aSXin Li- image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm, color_space); 1360*ec63e07aSXin Li- if (!image) { 1361*ec63e07aSXin Li- fclose(f); 1362*ec63e07aSXin Li- return NULL; 1363*ec63e07aSXin Li- } 1364*ec63e07aSXin Li- /* set image offset and reference grid */ 1365*ec63e07aSXin Li- image->x0 = cmptparm.x0; 1366*ec63e07aSXin Li- image->y0 = cmptparm.x0; 1367*ec63e07aSXin Li- image->x1 = cmptparm.w; 1368*ec63e07aSXin Li- image->y1 = cmptparm.h; 1369*ec63e07aSXin Li- 1370*ec63e07aSXin Li- /* set image data */ 1371*ec63e07aSXin Li- 1372*ec63e07aSXin Li- comp = &image->comps[0]; 1373*ec63e07aSXin Li- 1374*ec63e07aSXin Li- for (i = 0; i < w * h; i++) { 1375*ec63e07aSXin Li- int v; 1376*ec63e07aSXin Li- if (force8) { 1377*ec63e07aSXin Li- v = readuchar(f) + adjustS; 1378*ec63e07aSXin Li- v = (v << ushift) + (v >> dshift); 1379*ec63e07aSXin Li- comp->data[i] = (unsigned char)v; 1380*ec63e07aSXin Li- 1381*ec63e07aSXin Li- if (v > max) { 1382*ec63e07aSXin Li- max = v; 1383*ec63e07aSXin Li- } 1384*ec63e07aSXin Li- 1385*ec63e07aSXin Li- continue; 1386*ec63e07aSXin Li- } 1387*ec63e07aSXin Li- if (comp->prec == 8) { 1388*ec63e07aSXin Li- if (!comp->sgnd) { 1389*ec63e07aSXin Li- v = readuchar(f); 1390*ec63e07aSXin Li- } else { 1391*ec63e07aSXin Li- v = (char) readuchar(f); 1392*ec63e07aSXin Li- } 1393*ec63e07aSXin Li- } else if (comp->prec <= 16) { 1394*ec63e07aSXin Li- if (!comp->sgnd) { 1395*ec63e07aSXin Li- v = readushort(f, bigendian); 1396*ec63e07aSXin Li- } else { 1397*ec63e07aSXin Li- v = (short) readushort(f, bigendian); 1398*ec63e07aSXin Li- } 1399*ec63e07aSXin Li- } else { 1400*ec63e07aSXin Li- if (!comp->sgnd) { 1401*ec63e07aSXin Li- v = (int)readuint(f, bigendian); 1402*ec63e07aSXin Li- } else { 1403*ec63e07aSXin Li- v = (int) readuint(f, bigendian); 1404*ec63e07aSXin Li- } 1405*ec63e07aSXin Li- } 1406*ec63e07aSXin Li- if (v > max) { 1407*ec63e07aSXin Li- max = v; 1408*ec63e07aSXin Li- } 1409*ec63e07aSXin Li- comp->data[i] = v; 1410*ec63e07aSXin Li- } 1411*ec63e07aSXin Li- fclose(f); 1412*ec63e07aSXin Li- comp->bpp = (OPJ_UINT32)int_floorlog2(max) + 1; 1413*ec63e07aSXin Li- 1414*ec63e07aSXin Li- return image; 1415*ec63e07aSXin Li-} 1416*ec63e07aSXin Li- 1417*ec63e07aSXin Li-#define CLAMP(x,a,b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x))) 1418*ec63e07aSXin Li- 1419*ec63e07aSXin Li-static INLINE int clamp(const int value, const int prec, const int sgnd) 1420*ec63e07aSXin Li-{ 1421*ec63e07aSXin Li- if (sgnd) { 1422*ec63e07aSXin Li- if (prec <= 8) { 1423*ec63e07aSXin Li- return CLAMP(value, -128, 127); 1424*ec63e07aSXin Li- } else if (prec <= 16) { 1425*ec63e07aSXin Li- return CLAMP(value, -32768, 32767); 1426*ec63e07aSXin Li- } else { 1427*ec63e07aSXin Li- return CLAMP(value, -2147483647 - 1, 2147483647); 1428*ec63e07aSXin Li- } 1429*ec63e07aSXin Li- } else { 1430*ec63e07aSXin Li- if (prec <= 8) { 1431*ec63e07aSXin Li- return CLAMP(value, 0, 255); 1432*ec63e07aSXin Li- } else if (prec <= 16) { 1433*ec63e07aSXin Li- return CLAMP(value, 0, 65535); 1434*ec63e07aSXin Li- } else { 1435*ec63e07aSXin Li- return value; /*CLAMP(value,0,4294967295);*/ 1436*ec63e07aSXin Li- } 1437*ec63e07aSXin Li- } 1438*ec63e07aSXin Li-} 1439*ec63e07aSXin Li- 1440*ec63e07aSXin Li-int imagetopgx(opj_image_t * image, const char *outfile) 1441*ec63e07aSXin Li-{ 1442*ec63e07aSXin Li- int w, h; 1443*ec63e07aSXin Li- int i, j, fails = 1; 1444*ec63e07aSXin Li- unsigned int compno; 1445*ec63e07aSXin Li- FILE *fdest = NULL; 1446*ec63e07aSXin Li- 1447*ec63e07aSXin Li- for (compno = 0; compno < image->numcomps; compno++) { 1448*ec63e07aSXin Li- opj_image_comp_t *comp = &image->comps[compno]; 1449*ec63e07aSXin Li- char bname[256]; /* buffer for name */ 1450*ec63e07aSXin Li- char *name = bname; /* pointer */ 1451*ec63e07aSXin Li- int nbytes = 0; 1452*ec63e07aSXin Li- size_t res; 1453*ec63e07aSXin Li- const size_t olen = strlen(outfile); 1454*ec63e07aSXin Li- const size_t dotpos = olen - 4; 1455*ec63e07aSXin Li- const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */ 1456*ec63e07aSXin Li- 1457*ec63e07aSXin Li- if (outfile[dotpos] != '.') { 1458*ec63e07aSXin Li- /* `pgx` was recognized but there is no dot at expected position */ 1459*ec63e07aSXin Li- fprintf(stderr, "ERROR -> Impossible happen."); 1460*ec63e07aSXin Li- goto fin; 1461*ec63e07aSXin Li- } 1462*ec63e07aSXin Li- if (total > 256) { 1463*ec63e07aSXin Li- name = (char*)malloc(total + 1); 1464*ec63e07aSXin Li- if (name == NULL) { 1465*ec63e07aSXin Li- fprintf(stderr, "imagetopgx: memory out\n"); 1466*ec63e07aSXin Li- goto fin; 1467*ec63e07aSXin Li- } 1468*ec63e07aSXin Li- } 1469*ec63e07aSXin Li- strncpy(name, outfile, dotpos); 1470*ec63e07aSXin Li- sprintf(name + dotpos, "_%u.pgx", compno); 1471*ec63e07aSXin Li- fdest = fopen(name, "wb"); 1472*ec63e07aSXin Li- /* don't need name anymore */ 1473*ec63e07aSXin Li- 1474*ec63e07aSXin Li- if (!fdest) { 1475*ec63e07aSXin Li- 1476*ec63e07aSXin Li- fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); 1477*ec63e07aSXin Li- if (total > 256) { 1478*ec63e07aSXin Li- free(name); 1479*ec63e07aSXin Li- } 1480*ec63e07aSXin Li- goto fin; 1481*ec63e07aSXin Li- } 1482*ec63e07aSXin Li- 1483*ec63e07aSXin Li- w = (int)image->comps[compno].w; 1484*ec63e07aSXin Li- h = (int)image->comps[compno].h; 1485*ec63e07aSXin Li- 1486*ec63e07aSXin Li- fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, 1487*ec63e07aSXin Li- w, h); 1488*ec63e07aSXin Li- 1489*ec63e07aSXin Li- if (comp->prec <= 8) { 1490*ec63e07aSXin Li- nbytes = 1; 1491*ec63e07aSXin Li- } else if (comp->prec <= 16) { 1492*ec63e07aSXin Li- nbytes = 2; 1493*ec63e07aSXin Li- } else { 1494*ec63e07aSXin Li- nbytes = 4; 1495*ec63e07aSXin Li- } 1496*ec63e07aSXin Li- 1497*ec63e07aSXin Li- if (nbytes == 1) { 1498*ec63e07aSXin Li- unsigned char* line_buffer = malloc((size_t)w); 1499*ec63e07aSXin Li- if (line_buffer == NULL) { 1500*ec63e07aSXin Li- fprintf(stderr, "Out of memory"); 1501*ec63e07aSXin Li- if (total > 256) { 1502*ec63e07aSXin Li- free(name); 1503*ec63e07aSXin Li- } 1504*ec63e07aSXin Li- goto fin; 1505*ec63e07aSXin Li- } 1506*ec63e07aSXin Li- for (j = 0; j < h; j++) { 1507*ec63e07aSXin Li- if (comp->prec == 8 && comp->sgnd == 0) { 1508*ec63e07aSXin Li- for (i = 0; i < w; i++) { 1509*ec63e07aSXin Li- line_buffer[i] = (unsigned char)CLAMP(image->comps[compno].data[j * w + i], 0, 1510*ec63e07aSXin Li- 255); 1511*ec63e07aSXin Li- } 1512*ec63e07aSXin Li- } else { 1513*ec63e07aSXin Li- for (i = 0; i < w; i++) { 1514*ec63e07aSXin Li- line_buffer[i] = (unsigned char) 1515*ec63e07aSXin Li- clamp(image->comps[compno].data[j * w + i], 1516*ec63e07aSXin Li- (int)comp->prec, (int)comp->sgnd); 1517*ec63e07aSXin Li- } 1518*ec63e07aSXin Li- } 1519*ec63e07aSXin Li- res = fwrite(line_buffer, 1, (size_t)w, fdest); 1520*ec63e07aSXin Li- if (res != (size_t)w) { 1521*ec63e07aSXin Li- fprintf(stderr, "failed to write %d bytes for %s\n", w, name); 1522*ec63e07aSXin Li- if (total > 256) { 1523*ec63e07aSXin Li- free(name); 1524*ec63e07aSXin Li- } 1525*ec63e07aSXin Li- free(line_buffer); 1526*ec63e07aSXin Li- goto fin; 1527*ec63e07aSXin Li- } 1528*ec63e07aSXin Li- } 1529*ec63e07aSXin Li- free(line_buffer); 1530*ec63e07aSXin Li- } else { 1531*ec63e07aSXin Li- 1532*ec63e07aSXin Li- for (i = 0; i < w * h; i++) { 1533*ec63e07aSXin Li- /* FIXME: clamp func is being called within a loop */ 1534*ec63e07aSXin Li- const int val = clamp(image->comps[compno].data[i], 1535*ec63e07aSXin Li- (int)comp->prec, (int)comp->sgnd); 1536*ec63e07aSXin Li- 1537*ec63e07aSXin Li- for (j = nbytes - 1; j >= 0; j--) { 1538*ec63e07aSXin Li- int v = (int)(val >> (j * 8)); 1539*ec63e07aSXin Li- unsigned char byte = (unsigned char)v; 1540*ec63e07aSXin Li- res = fwrite(&byte, 1, 1, fdest); 1541*ec63e07aSXin Li- 1542*ec63e07aSXin Li- if (res < 1) { 1543*ec63e07aSXin Li- fprintf(stderr, "failed to write 1 byte for %s\n", name); 1544*ec63e07aSXin Li- if (total > 256) { 1545*ec63e07aSXin Li- free(name); 1546*ec63e07aSXin Li- } 1547*ec63e07aSXin Li- goto fin; 1548*ec63e07aSXin Li- } 1549*ec63e07aSXin Li- } 1550*ec63e07aSXin Li- } 1551*ec63e07aSXin Li- } 1552*ec63e07aSXin Li- 1553*ec63e07aSXin Li- if (total > 256) { 1554*ec63e07aSXin Li- free(name); 1555*ec63e07aSXin Li- } 1556*ec63e07aSXin Li- fclose(fdest); 1557*ec63e07aSXin Li- fdest = NULL; 1558*ec63e07aSXin Li- } 1559*ec63e07aSXin Li- fails = 0; 1560*ec63e07aSXin Li-fin: 1561*ec63e07aSXin Li- if (fdest) { 1562*ec63e07aSXin Li- fclose(fdest); 1563*ec63e07aSXin Li- } 1564*ec63e07aSXin Li- 1565*ec63e07aSXin Li- return fails; 1566*ec63e07aSXin Li-} 1567*ec63e07aSXin Li- 1568*ec63e07aSXin Li-/* -->> -->> -->> -->> 1569*ec63e07aSXin Li- 1570*ec63e07aSXin Li-PNM IMAGE FORMAT 1571*ec63e07aSXin Li- 1572*ec63e07aSXin Li-<<-- <<-- <<-- <<-- */ 1573*ec63e07aSXin Li- 1574*ec63e07aSXin Li-struct pnm_header { 1575*ec63e07aSXin Li- int width, height, maxval, depth, format; 1576*ec63e07aSXin Li- char rgb, rgba, gray, graya, bw; 1577*ec63e07aSXin Li- char ok; 1578*ec63e07aSXin Li-}; 1579*ec63e07aSXin Li- 1580*ec63e07aSXin Li-static char *skip_white(char *s) 1581*ec63e07aSXin Li-{ 1582*ec63e07aSXin Li- if (s != NULL) { 1583*ec63e07aSXin Li- while (*s) { 1584*ec63e07aSXin Li- if (*s == '\n' || *s == '\r') { 1585*ec63e07aSXin Li- return NULL; 1586*ec63e07aSXin Li- } 1587*ec63e07aSXin Li- if (isspace(*s)) { 1588*ec63e07aSXin Li- ++s; 1589*ec63e07aSXin Li- continue; 1590*ec63e07aSXin Li- } 1591*ec63e07aSXin Li- return s; 1592*ec63e07aSXin Li- } 1593*ec63e07aSXin Li- } 1594*ec63e07aSXin Li- return NULL; 1595*ec63e07aSXin Li-} 1596*ec63e07aSXin Li- 1597*ec63e07aSXin Li-static char *skip_int(char *start, int *out_n) 1598*ec63e07aSXin Li-{ 1599*ec63e07aSXin Li- char *s; 1600*ec63e07aSXin Li- char c; 1601*ec63e07aSXin Li- 1602*ec63e07aSXin Li- *out_n = 0; 1603*ec63e07aSXin Li- 1604*ec63e07aSXin Li- s = skip_white(start); 1605*ec63e07aSXin Li- if (s == NULL) { 1606*ec63e07aSXin Li- return NULL; 1607*ec63e07aSXin Li- } 1608*ec63e07aSXin Li- start = s; 1609*ec63e07aSXin Li- 1610*ec63e07aSXin Li- while (*s) { 1611*ec63e07aSXin Li- if (!isdigit(*s)) { 1612*ec63e07aSXin Li- break; 1613*ec63e07aSXin Li- } 1614*ec63e07aSXin Li- ++s; 1615*ec63e07aSXin Li- } 1616*ec63e07aSXin Li- c = *s; 1617*ec63e07aSXin Li- *s = 0; 1618*ec63e07aSXin Li- *out_n = atoi(start); 1619*ec63e07aSXin Li- *s = c; 1620*ec63e07aSXin Li- return s; 1621*ec63e07aSXin Li-} 1622*ec63e07aSXin Li- 1623*ec63e07aSXin Li-static char *skip_idf(char *start, char out_idf[256]) 1624*ec63e07aSXin Li-{ 1625*ec63e07aSXin Li- char *s; 1626*ec63e07aSXin Li- char c; 1627*ec63e07aSXin Li- 1628*ec63e07aSXin Li- s = skip_white(start); 1629*ec63e07aSXin Li- if (s == NULL) { 1630*ec63e07aSXin Li- return NULL; 1631*ec63e07aSXin Li- } 1632*ec63e07aSXin Li- start = s; 1633*ec63e07aSXin Li- 1634*ec63e07aSXin Li- while (*s) { 1635*ec63e07aSXin Li- if (isalpha(*s) || *s == '_') { 1636*ec63e07aSXin Li- ++s; 1637*ec63e07aSXin Li- continue; 1638*ec63e07aSXin Li- } 1639*ec63e07aSXin Li- break; 1640*ec63e07aSXin Li- } 1641*ec63e07aSXin Li- c = *s; 1642*ec63e07aSXin Li- *s = 0; 1643*ec63e07aSXin Li- strncpy(out_idf, start, 255); 1644*ec63e07aSXin Li- *s = c; 1645*ec63e07aSXin Li- return s; 1646*ec63e07aSXin Li-} 1647*ec63e07aSXin Li- 1648*ec63e07aSXin Li-static void read_pnm_header(FILE *reader, struct pnm_header *ph) 1649*ec63e07aSXin Li-{ 1650*ec63e07aSXin Li- int format, end, ttype; 1651*ec63e07aSXin Li- char idf[256], type[256]; 1652*ec63e07aSXin Li- char line[256]; 1653*ec63e07aSXin Li- 1654*ec63e07aSXin Li- if (fgets(line, 250, reader) == NULL) { 1655*ec63e07aSXin Li- fprintf(stderr, "\nWARNING: fgets return a NULL value"); 1656*ec63e07aSXin Li- return; 1657*ec63e07aSXin Li- } 1658*ec63e07aSXin Li- 1659*ec63e07aSXin Li- if (line[0] != 'P') { 1660*ec63e07aSXin Li- fprintf(stderr, "read_pnm_header:PNM:magic P missing\n"); 1661*ec63e07aSXin Li- return; 1662*ec63e07aSXin Li- } 1663*ec63e07aSXin Li- format = atoi(line + 1); 1664*ec63e07aSXin Li- if (format < 1 || format > 7) { 1665*ec63e07aSXin Li- fprintf(stderr, "read_pnm_header:magic format %d invalid\n", format); 1666*ec63e07aSXin Li- return; 1667*ec63e07aSXin Li- } 1668*ec63e07aSXin Li- ph->format = format; 1669*ec63e07aSXin Li- ttype = end = 0; 1670*ec63e07aSXin Li- 1671*ec63e07aSXin Li- while (fgets(line, 250, reader)) { 1672*ec63e07aSXin Li- char *s; 1673*ec63e07aSXin Li- int allow_null = 0; 1674*ec63e07aSXin Li- 1675*ec63e07aSXin Li- if (*line == '#') { 1676*ec63e07aSXin Li- continue; 1677*ec63e07aSXin Li- } 1678*ec63e07aSXin Li- 1679*ec63e07aSXin Li- s = line; 1680*ec63e07aSXin Li- 1681*ec63e07aSXin Li- if (format == 7) { 1682*ec63e07aSXin Li- s = skip_idf(s, idf); 1683*ec63e07aSXin Li- 1684*ec63e07aSXin Li- if (s == NULL || *s == 0) { 1685*ec63e07aSXin Li- return; 1686*ec63e07aSXin Li- } 1687*ec63e07aSXin Li- 1688*ec63e07aSXin Li- if (strcmp(idf, "ENDHDR") == 0) { 1689*ec63e07aSXin Li- end = 1; 1690*ec63e07aSXin Li- break; 1691*ec63e07aSXin Li- } 1692*ec63e07aSXin Li- if (strcmp(idf, "WIDTH") == 0) { 1693*ec63e07aSXin Li- s = skip_int(s, &ph->width); 1694*ec63e07aSXin Li- if (s == NULL || *s == 0) { 1695*ec63e07aSXin Li- return; 1696*ec63e07aSXin Li- } 1697*ec63e07aSXin Li- 1698*ec63e07aSXin Li- continue; 1699*ec63e07aSXin Li- } 1700*ec63e07aSXin Li- if (strcmp(idf, "HEIGHT") == 0) { 1701*ec63e07aSXin Li- s = skip_int(s, &ph->height); 1702*ec63e07aSXin Li- if (s == NULL || *s == 0) { 1703*ec63e07aSXin Li- return; 1704*ec63e07aSXin Li- } 1705*ec63e07aSXin Li- 1706*ec63e07aSXin Li- continue; 1707*ec63e07aSXin Li- } 1708*ec63e07aSXin Li- if (strcmp(idf, "DEPTH") == 0) { 1709*ec63e07aSXin Li- s = skip_int(s, &ph->depth); 1710*ec63e07aSXin Li- if (s == NULL || *s == 0) { 1711*ec63e07aSXin Li- return; 1712*ec63e07aSXin Li- } 1713*ec63e07aSXin Li- 1714*ec63e07aSXin Li- continue; 1715*ec63e07aSXin Li- } 1716*ec63e07aSXin Li- if (strcmp(idf, "MAXVAL") == 0) { 1717*ec63e07aSXin Li- s = skip_int(s, &ph->maxval); 1718*ec63e07aSXin Li- if (s == NULL || *s == 0) { 1719*ec63e07aSXin Li- return; 1720*ec63e07aSXin Li- } 1721*ec63e07aSXin Li- 1722*ec63e07aSXin Li- continue; 1723*ec63e07aSXin Li- } 1724*ec63e07aSXin Li- if (strcmp(idf, "TUPLTYPE") == 0) { 1725*ec63e07aSXin Li- s = skip_idf(s, type); 1726*ec63e07aSXin Li- if (s == NULL || *s == 0) { 1727*ec63e07aSXin Li- return; 1728*ec63e07aSXin Li- } 1729*ec63e07aSXin Li- 1730*ec63e07aSXin Li- if (strcmp(type, "BLACKANDWHITE") == 0) { 1731*ec63e07aSXin Li- ph->bw = 1; 1732*ec63e07aSXin Li- ttype = 1; 1733*ec63e07aSXin Li- continue; 1734*ec63e07aSXin Li- } 1735*ec63e07aSXin Li- if (strcmp(type, "GRAYSCALE") == 0) { 1736*ec63e07aSXin Li- ph->gray = 1; 1737*ec63e07aSXin Li- ttype = 1; 1738*ec63e07aSXin Li- continue; 1739*ec63e07aSXin Li- } 1740*ec63e07aSXin Li- if (strcmp(type, "GRAYSCALE_ALPHA") == 0) { 1741*ec63e07aSXin Li- ph->graya = 1; 1742*ec63e07aSXin Li- ttype = 1; 1743*ec63e07aSXin Li- continue; 1744*ec63e07aSXin Li- } 1745*ec63e07aSXin Li- if (strcmp(type, "RGB") == 0) { 1746*ec63e07aSXin Li- ph->rgb = 1; 1747*ec63e07aSXin Li- ttype = 1; 1748*ec63e07aSXin Li- continue; 1749*ec63e07aSXin Li- } 1750*ec63e07aSXin Li- if (strcmp(type, "RGB_ALPHA") == 0) { 1751*ec63e07aSXin Li- ph->rgba = 1; 1752*ec63e07aSXin Li- ttype = 1; 1753*ec63e07aSXin Li- continue; 1754*ec63e07aSXin Li- } 1755*ec63e07aSXin Li- fprintf(stderr, "read_pnm_header:unknown P7 TUPLTYPE %s\n", type); 1756*ec63e07aSXin Li- return; 1757*ec63e07aSXin Li- } 1758*ec63e07aSXin Li- fprintf(stderr, "read_pnm_header:unknown P7 idf %s\n", idf); 1759*ec63e07aSXin Li- return; 1760*ec63e07aSXin Li- } /* if(format == 7) */ 1761*ec63e07aSXin Li- 1762*ec63e07aSXin Li- /* Here format is in range [1,6] */ 1763*ec63e07aSXin Li- if (ph->width == 0) { 1764*ec63e07aSXin Li- s = skip_int(s, &ph->width); 1765*ec63e07aSXin Li- if ((s == NULL) || (*s == 0) || (ph->width < 1)) { 1766*ec63e07aSXin Li- return; 1767*ec63e07aSXin Li- } 1768*ec63e07aSXin Li- allow_null = 1; 1769*ec63e07aSXin Li- } 1770*ec63e07aSXin Li- if (ph->height == 0) { 1771*ec63e07aSXin Li- s = skip_int(s, &ph->height); 1772*ec63e07aSXin Li- if ((s == NULL) && allow_null) { 1773*ec63e07aSXin Li- continue; 1774*ec63e07aSXin Li- } 1775*ec63e07aSXin Li- if ((s == NULL) || (*s == 0) || (ph->height < 1)) { 1776*ec63e07aSXin Li- return; 1777*ec63e07aSXin Li- } 1778*ec63e07aSXin Li- if (format == 1 || format == 4) { 1779*ec63e07aSXin Li- break; 1780*ec63e07aSXin Li- } 1781*ec63e07aSXin Li- allow_null = 1; 1782*ec63e07aSXin Li- } 1783*ec63e07aSXin Li- /* here, format is in P2, P3, P5, P6 */ 1784*ec63e07aSXin Li- s = skip_int(s, &ph->maxval); 1785*ec63e07aSXin Li- if ((s == NULL) && allow_null) { 1786*ec63e07aSXin Li- continue; 1787*ec63e07aSXin Li- } 1788*ec63e07aSXin Li- if ((s == NULL) || (*s == 0)) { 1789*ec63e07aSXin Li- return; 1790*ec63e07aSXin Li- } 1791*ec63e07aSXin Li- break; 1792*ec63e07aSXin Li- }/* while(fgets( ) */ 1793*ec63e07aSXin Li- if (format == 2 || format == 3 || format > 4) { 1794*ec63e07aSXin Li- if (ph->maxval < 1 || ph->maxval > 65535) { 1795*ec63e07aSXin Li- return; 1796*ec63e07aSXin Li- } 1797*ec63e07aSXin Li- } 1798*ec63e07aSXin Li- if (ph->width < 1 || ph->height < 1) { 1799*ec63e07aSXin Li- return; 1800*ec63e07aSXin Li- } 1801*ec63e07aSXin Li- 1802*ec63e07aSXin Li- if (format == 7) { 1803*ec63e07aSXin Li- if (!end) { 1804*ec63e07aSXin Li- fprintf(stderr, "read_pnm_header:P7 without ENDHDR\n"); 1805*ec63e07aSXin Li- return; 1806*ec63e07aSXin Li- } 1807*ec63e07aSXin Li- if (ph->depth < 1 || ph->depth > 4) { 1808*ec63e07aSXin Li- return; 1809*ec63e07aSXin Li- } 1810*ec63e07aSXin Li- 1811*ec63e07aSXin Li- if (ttype) { 1812*ec63e07aSXin Li- ph->ok = 1; 1813*ec63e07aSXin Li- } 1814*ec63e07aSXin Li- } else { 1815*ec63e07aSXin Li- ph->ok = 1; 1816*ec63e07aSXin Li- if (format == 1 || format == 4) { 1817*ec63e07aSXin Li- ph->maxval = 255; 1818*ec63e07aSXin Li- } 1819*ec63e07aSXin Li- } 1820*ec63e07aSXin Li-} 1821*ec63e07aSXin Li- 1822*ec63e07aSXin Li-static int has_prec(int val) 1823*ec63e07aSXin Li-{ 1824*ec63e07aSXin Li- if (val < 2) { 1825*ec63e07aSXin Li- return 1; 1826*ec63e07aSXin Li- } 1827*ec63e07aSXin Li- if (val < 4) { 1828*ec63e07aSXin Li- return 2; 1829*ec63e07aSXin Li- } 1830*ec63e07aSXin Li- if (val < 8) { 1831*ec63e07aSXin Li- return 3; 1832*ec63e07aSXin Li- } 1833*ec63e07aSXin Li- if (val < 16) { 1834*ec63e07aSXin Li- return 4; 1835*ec63e07aSXin Li- } 1836*ec63e07aSXin Li- if (val < 32) { 1837*ec63e07aSXin Li- return 5; 1838*ec63e07aSXin Li- } 1839*ec63e07aSXin Li- if (val < 64) { 1840*ec63e07aSXin Li- return 6; 1841*ec63e07aSXin Li- } 1842*ec63e07aSXin Li- if (val < 128) { 1843*ec63e07aSXin Li- return 7; 1844*ec63e07aSXin Li- } 1845*ec63e07aSXin Li- if (val < 256) { 1846*ec63e07aSXin Li- return 8; 1847*ec63e07aSXin Li- } 1848*ec63e07aSXin Li- if (val < 512) { 1849*ec63e07aSXin Li- return 9; 1850*ec63e07aSXin Li- } 1851*ec63e07aSXin Li- if (val < 1024) { 1852*ec63e07aSXin Li- return 10; 1853*ec63e07aSXin Li- } 1854*ec63e07aSXin Li- if (val < 2048) { 1855*ec63e07aSXin Li- return 11; 1856*ec63e07aSXin Li- } 1857*ec63e07aSXin Li- if (val < 4096) { 1858*ec63e07aSXin Li- return 12; 1859*ec63e07aSXin Li- } 1860*ec63e07aSXin Li- if (val < 8192) { 1861*ec63e07aSXin Li- return 13; 1862*ec63e07aSXin Li- } 1863*ec63e07aSXin Li- if (val < 16384) { 1864*ec63e07aSXin Li- return 14; 1865*ec63e07aSXin Li- } 1866*ec63e07aSXin Li- if (val < 32768) { 1867*ec63e07aSXin Li- return 15; 1868*ec63e07aSXin Li- } 1869*ec63e07aSXin Li- return 16; 1870*ec63e07aSXin Li-} 1871*ec63e07aSXin Li- 1872*ec63e07aSXin Li-opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) 1873*ec63e07aSXin Li-{ 1874*ec63e07aSXin Li- int subsampling_dx = parameters->subsampling_dx; 1875*ec63e07aSXin Li- int subsampling_dy = parameters->subsampling_dy; 1876*ec63e07aSXin Li- 1877*ec63e07aSXin Li- FILE *fp = NULL; 1878*ec63e07aSXin Li- int i, compno, numcomps, w, h, prec, format; 1879*ec63e07aSXin Li- OPJ_COLOR_SPACE color_space; 1880*ec63e07aSXin Li- opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */ 1881*ec63e07aSXin Li- opj_image_t * image = NULL; 1882*ec63e07aSXin Li- struct pnm_header header_info; 1883*ec63e07aSXin Li- 1884*ec63e07aSXin Li- if ((fp = fopen(filename, "rb")) == NULL) { 1885*ec63e07aSXin Li- fprintf(stderr, "pnmtoimage:Failed to open %s for reading!\n", filename); 1886*ec63e07aSXin Li- return NULL; 1887*ec63e07aSXin Li- } 1888*ec63e07aSXin Li- memset(&header_info, 0, sizeof(struct pnm_header)); 1889*ec63e07aSXin Li- 1890*ec63e07aSXin Li- read_pnm_header(fp, &header_info); 1891*ec63e07aSXin Li- 1892*ec63e07aSXin Li- if (!header_info.ok) { 1893*ec63e07aSXin Li- fclose(fp); 1894*ec63e07aSXin Li- return NULL; 1895*ec63e07aSXin Li- } 1896*ec63e07aSXin Li- 1897*ec63e07aSXin Li- if (header_info.width == 0 1898*ec63e07aSXin Li- || header_info.height == 0 1899*ec63e07aSXin Li- || (header_info.format == 7 && header_info.depth == 0)) { 1900*ec63e07aSXin Li- fclose(fp); 1901*ec63e07aSXin Li- return NULL; 1902*ec63e07aSXin Li- } 1903*ec63e07aSXin Li- 1904*ec63e07aSXin Li- /* This limitation could be removed by making sure to use size_t below */ 1905*ec63e07aSXin Li- if (header_info.height != 0 && 1906*ec63e07aSXin Li- header_info.width > INT_MAX / header_info.height) { 1907*ec63e07aSXin Li- fprintf(stderr, "pnmtoimage:Image %dx%d too big!\n", 1908*ec63e07aSXin Li- header_info.width, header_info.height); 1909*ec63e07aSXin Li- fclose(fp); 1910*ec63e07aSXin Li- return NULL; 1911*ec63e07aSXin Li- } 1912*ec63e07aSXin Li- 1913*ec63e07aSXin Li- format = header_info.format; 1914*ec63e07aSXin Li- 1915*ec63e07aSXin Li- switch (format) { 1916*ec63e07aSXin Li- case 1: /* ascii bitmap */ 1917*ec63e07aSXin Li- case 4: /* raw bitmap */ 1918*ec63e07aSXin Li- numcomps = 1; 1919*ec63e07aSXin Li- break; 1920*ec63e07aSXin Li- 1921*ec63e07aSXin Li- case 2: /* ascii greymap */ 1922*ec63e07aSXin Li- case 5: /* raw greymap */ 1923*ec63e07aSXin Li- numcomps = 1; 1924*ec63e07aSXin Li- break; 1925*ec63e07aSXin Li- 1926*ec63e07aSXin Li- case 3: /* ascii pixmap */ 1927*ec63e07aSXin Li- case 6: /* raw pixmap */ 1928*ec63e07aSXin Li- numcomps = 3; 1929*ec63e07aSXin Li- break; 1930*ec63e07aSXin Li- 1931*ec63e07aSXin Li- case 7: /* arbitrary map */ 1932*ec63e07aSXin Li- numcomps = header_info.depth; 1933*ec63e07aSXin Li- break; 1934*ec63e07aSXin Li- 1935*ec63e07aSXin Li- default: 1936*ec63e07aSXin Li- fclose(fp); 1937*ec63e07aSXin Li- return NULL; 1938*ec63e07aSXin Li- } 1939*ec63e07aSXin Li- if (numcomps < 3) { 1940*ec63e07aSXin Li- color_space = OPJ_CLRSPC_GRAY; /* GRAY, GRAYA */ 1941*ec63e07aSXin Li- } else { 1942*ec63e07aSXin Li- color_space = OPJ_CLRSPC_SRGB; /* RGB, RGBA */ 1943*ec63e07aSXin Li- } 1944*ec63e07aSXin Li- 1945*ec63e07aSXin Li- prec = has_prec(header_info.maxval); 1946*ec63e07aSXin Li- 1947*ec63e07aSXin Li- if (prec < 8) { 1948*ec63e07aSXin Li- prec = 8; 1949*ec63e07aSXin Li- } 1950*ec63e07aSXin Li- 1951*ec63e07aSXin Li- w = header_info.width; 1952*ec63e07aSXin Li- h = header_info.height; 1953*ec63e07aSXin Li- subsampling_dx = parameters->subsampling_dx; 1954*ec63e07aSXin Li- subsampling_dy = parameters->subsampling_dy; 1955*ec63e07aSXin Li- 1956*ec63e07aSXin Li- memset(&cmptparm[0], 0, (size_t)numcomps * sizeof(opj_image_cmptparm_t)); 1957*ec63e07aSXin Li- 1958*ec63e07aSXin Li- for (i = 0; i < numcomps; i++) { 1959*ec63e07aSXin Li- cmptparm[i].prec = (OPJ_UINT32)prec; 1960*ec63e07aSXin Li- cmptparm[i].bpp = (OPJ_UINT32)prec; 1961*ec63e07aSXin Li- cmptparm[i].sgnd = 0; 1962*ec63e07aSXin Li- cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; 1963*ec63e07aSXin Li- cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; 1964*ec63e07aSXin Li- cmptparm[i].w = (OPJ_UINT32)w; 1965*ec63e07aSXin Li- cmptparm[i].h = (OPJ_UINT32)h; 1966*ec63e07aSXin Li- } 1967*ec63e07aSXin Li- image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); 1968*ec63e07aSXin Li- 1969*ec63e07aSXin Li- if (!image) { 1970*ec63e07aSXin Li- fclose(fp); 1971*ec63e07aSXin Li- return NULL; 1972*ec63e07aSXin Li- } 1973*ec63e07aSXin Li- 1974*ec63e07aSXin Li- /* set image offset and reference grid */ 1975*ec63e07aSXin Li- image->x0 = (OPJ_UINT32)parameters->image_offset_x0; 1976*ec63e07aSXin Li- image->y0 = (OPJ_UINT32)parameters->image_offset_y0; 1977*ec63e07aSXin Li- image->x1 = (OPJ_UINT32)(parameters->image_offset_x0 + (w - 1) * subsampling_dx 1978*ec63e07aSXin Li- + 1); 1979*ec63e07aSXin Li- image->y1 = (OPJ_UINT32)(parameters->image_offset_y0 + (h - 1) * subsampling_dy 1980*ec63e07aSXin Li- + 1); 1981*ec63e07aSXin Li- 1982*ec63e07aSXin Li- if ((format == 2) || (format == 3)) { /* ascii pixmap */ 1983*ec63e07aSXin Li- unsigned int index; 1984*ec63e07aSXin Li- 1985*ec63e07aSXin Li- for (i = 0; i < w * h; i++) { 1986*ec63e07aSXin Li- for (compno = 0; compno < numcomps; compno++) { 1987*ec63e07aSXin Li- index = 0; 1988*ec63e07aSXin Li- if (fscanf(fp, "%u", &index) != 1) { 1989*ec63e07aSXin Li- fprintf(stderr, "Missing data. Quitting.\n"); 1990*ec63e07aSXin Li- opj_image_destroy(image); 1991*ec63e07aSXin Li- fclose(fp); 1992*ec63e07aSXin Li- return NULL; 1993*ec63e07aSXin Li- } 1994*ec63e07aSXin Li- 1995*ec63e07aSXin Li- image->comps[compno].data[i] = (OPJ_INT32)(index * 255) / header_info.maxval; 1996*ec63e07aSXin Li- } 1997*ec63e07aSXin Li- } 1998*ec63e07aSXin Li- } else if ((format == 5) 1999*ec63e07aSXin Li- || (format == 6) 2000*ec63e07aSXin Li- || ((format == 7) 2001*ec63e07aSXin Li- && (header_info.gray || header_info.graya 2002*ec63e07aSXin Li- || header_info.rgb || header_info.rgba))) { /* binary pixmap */ 2003*ec63e07aSXin Li- unsigned char c0, c1, one; 2004*ec63e07aSXin Li- 2005*ec63e07aSXin Li- one = (prec < 9); 2006*ec63e07aSXin Li- 2007*ec63e07aSXin Li- for (i = 0; i < w * h; i++) { 2008*ec63e07aSXin Li- for (compno = 0; compno < numcomps; compno++) { 2009*ec63e07aSXin Li- if (!fread(&c0, 1, 1, fp)) { 2010*ec63e07aSXin Li- fprintf(stderr, "Missing data. Quitting.\n"); 2011*ec63e07aSXin Li- opj_image_destroy(image); 2012*ec63e07aSXin Li- fclose(fp); 2013*ec63e07aSXin Li- return NULL; 2014*ec63e07aSXin Li- } 2015*ec63e07aSXin Li- if (one) { 2016*ec63e07aSXin Li- image->comps[compno].data[i] = c0; 2017*ec63e07aSXin Li- } else { 2018*ec63e07aSXin Li- if (!fread(&c1, 1, 1, fp)) { 2019*ec63e07aSXin Li- fprintf(stderr, "Missing data. Quitting.\n"); 2020*ec63e07aSXin Li- opj_image_destroy(image); 2021*ec63e07aSXin Li- fclose(fp); 2022*ec63e07aSXin Li- return NULL; 2023*ec63e07aSXin Li- } 2024*ec63e07aSXin Li- /* netpbm: */ 2025*ec63e07aSXin Li- image->comps[compno].data[i] = ((c0 << 8) | c1); 2026*ec63e07aSXin Li- } 2027*ec63e07aSXin Li- } 2028*ec63e07aSXin Li- } 2029*ec63e07aSXin Li- } else if (format == 1) { /* ascii bitmap */ 2030*ec63e07aSXin Li- for (i = 0; i < w * h; i++) { 2031*ec63e07aSXin Li- unsigned int index; 2032*ec63e07aSXin Li- 2033*ec63e07aSXin Li- if (fscanf(fp, "%u", &index) != 1) { 2034*ec63e07aSXin Li- fprintf(stderr, "Missing data. Quitting.\n"); 2035*ec63e07aSXin Li- opj_image_destroy(image); 2036*ec63e07aSXin Li- fclose(fp); 2037*ec63e07aSXin Li- return NULL; 2038*ec63e07aSXin Li- } 2039*ec63e07aSXin Li- 2040*ec63e07aSXin Li- image->comps[0].data[i] = (index ? 0 : 255); 2041*ec63e07aSXin Li- } 2042*ec63e07aSXin Li- } else if (format == 4) { 2043*ec63e07aSXin Li- int x, y, bit; 2044*ec63e07aSXin Li- int uc; 2045*ec63e07aSXin Li- 2046*ec63e07aSXin Li- i = 0; 2047*ec63e07aSXin Li- for (y = 0; y < h; ++y) { 2048*ec63e07aSXin Li- bit = -1; 2049*ec63e07aSXin Li- uc = 0; 2050*ec63e07aSXin Li- 2051*ec63e07aSXin Li- for (x = 0; x < w; ++x) { 2052*ec63e07aSXin Li- if (bit == -1) { 2053*ec63e07aSXin Li- bit = 7; 2054*ec63e07aSXin Li- uc = getc(fp); 2055*ec63e07aSXin Li- if (uc == EOF) { 2056*ec63e07aSXin Li- fprintf(stderr, "Missing data. Quitting.\n"); 2057*ec63e07aSXin Li- opj_image_destroy(image); 2058*ec63e07aSXin Li- fclose(fp); 2059*ec63e07aSXin Li- return NULL; 2060*ec63e07aSXin Li- } 2061*ec63e07aSXin Li- } 2062*ec63e07aSXin Li- image->comps[0].data[i] = ((((unsigned char)uc >> bit) & 1) ? 0 : 255); 2063*ec63e07aSXin Li- --bit; 2064*ec63e07aSXin Li- ++i; 2065*ec63e07aSXin Li- } 2066*ec63e07aSXin Li- } 2067*ec63e07aSXin Li- } else if ((format == 7 && header_info.bw)) { /*MONO*/ 2068*ec63e07aSXin Li- unsigned char uc; 2069*ec63e07aSXin Li- 2070*ec63e07aSXin Li- for (i = 0; i < w * h; ++i) { 2071*ec63e07aSXin Li- if (!fread(&uc, 1, 1, fp)) { 2072*ec63e07aSXin Li- fprintf(stderr, "Missing data. Quitting.\n"); 2073*ec63e07aSXin Li- opj_image_destroy(image); 2074*ec63e07aSXin Li- fclose(fp); 2075*ec63e07aSXin Li- return NULL; 2076*ec63e07aSXin Li- } 2077*ec63e07aSXin Li- image->comps[0].data[i] = (uc & 1) ? 0 : 255; 2078*ec63e07aSXin Li- } 2079*ec63e07aSXin Li- } 2080*ec63e07aSXin Li- fclose(fp); 2081*ec63e07aSXin Li- 2082*ec63e07aSXin Li- return image; 2083*ec63e07aSXin Li-}/* pnmtoimage() */ 2084*ec63e07aSXin Li- 2085*ec63e07aSXin Li-static int are_comps_similar(opj_image_t * image) 2086*ec63e07aSXin Li-{ 2087*ec63e07aSXin Li- unsigned int i; 2088*ec63e07aSXin Li- for (i = 1; i < image->numcomps; i++) { 2089*ec63e07aSXin Li- if (image->comps[0].dx != image->comps[i].dx || 2090*ec63e07aSXin Li- image->comps[0].dy != image->comps[i].dy || 2091*ec63e07aSXin Li- (i <= 2 && 2092*ec63e07aSXin Li- (image->comps[0].prec != image->comps[i].prec || 2093*ec63e07aSXin Li- image->comps[0].sgnd != image->comps[i].sgnd))) { 2094*ec63e07aSXin Li- return OPJ_FALSE; 2095*ec63e07aSXin Li- } 2096*ec63e07aSXin Li- } 2097*ec63e07aSXin Li- return OPJ_TRUE; 2098*ec63e07aSXin Li-} 2099*ec63e07aSXin Li- 2100*ec63e07aSXin Li- 2101*ec63e07aSXin Li-int imagetopnm(opj_image_t * image, const char *outfile, int force_split) 2102*ec63e07aSXin Li-{ 2103*ec63e07aSXin Li- int *red, *green, *blue, *alpha; 2104*ec63e07aSXin Li- int wr, hr, max; 2105*ec63e07aSXin Li- int i; 2106*ec63e07aSXin Li- unsigned int compno, ncomp; 2107*ec63e07aSXin Li- int adjustR, adjustG, adjustB, adjustA; 2108*ec63e07aSXin Li- int fails, two, want_gray, has_alpha, triple; 2109*ec63e07aSXin Li- int prec, v; 2110*ec63e07aSXin Li- FILE *fdest = NULL; 2111*ec63e07aSXin Li- const char *tmp = outfile; 2112*ec63e07aSXin Li- char *destname; 2113*ec63e07aSXin Li- 2114*ec63e07aSXin Li- alpha = NULL; 2115*ec63e07aSXin Li- 2116*ec63e07aSXin Li- if ((prec = (int)image->comps[0].prec) > 16) { 2117*ec63e07aSXin Li- fprintf(stderr, "%s:%d:imagetopnm\n\tprecision %d is larger than 16" 2118*ec63e07aSXin Li- "\n\t: refused.\n", __FILE__, __LINE__, prec); 2119*ec63e07aSXin Li- return 1; 2120*ec63e07aSXin Li- } 2121*ec63e07aSXin Li- two = has_alpha = 0; 2122*ec63e07aSXin Li- fails = 1; 2123*ec63e07aSXin Li- ncomp = image->numcomps; 2124*ec63e07aSXin Li- 2125*ec63e07aSXin Li- while (*tmp) { 2126*ec63e07aSXin Li- ++tmp; 2127*ec63e07aSXin Li- } 2128*ec63e07aSXin Li- tmp -= 2; 2129*ec63e07aSXin Li- want_gray = (*tmp == 'g' || *tmp == 'G'); 2130*ec63e07aSXin Li- ncomp = image->numcomps; 2131*ec63e07aSXin Li- 2132*ec63e07aSXin Li- if (want_gray) { 2133*ec63e07aSXin Li- ncomp = 1; 2134*ec63e07aSXin Li- } 2135*ec63e07aSXin Li- 2136*ec63e07aSXin Li- if ((force_split == 0) && ncomp >= 2 && 2137*ec63e07aSXin Li- are_comps_similar(image)) { 2138*ec63e07aSXin Li- fdest = fopen(outfile, "wb"); 2139*ec63e07aSXin Li- 2140*ec63e07aSXin Li- if (!fdest) { 2141*ec63e07aSXin Li- fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); 2142*ec63e07aSXin Li- return fails; 2143*ec63e07aSXin Li- } 2144*ec63e07aSXin Li- two = (prec > 8); 2145*ec63e07aSXin Li- triple = (ncomp > 2); 2146*ec63e07aSXin Li- wr = (int)image->comps[0].w; 2147*ec63e07aSXin Li- hr = (int)image->comps[0].h; 2148*ec63e07aSXin Li- max = (1 << prec) - 1; 2149*ec63e07aSXin Li- has_alpha = (ncomp == 4 || ncomp == 2); 2150*ec63e07aSXin Li- 2151*ec63e07aSXin Li- red = image->comps[0].data; 2152*ec63e07aSXin Li- if (red == NULL) { 2153*ec63e07aSXin Li- fprintf(stderr, 2154*ec63e07aSXin Li- "imagetopnm: planes[%d] == NULL.\n", 0); 2155*ec63e07aSXin Li- fprintf(stderr, "\tAborting\n"); 2156*ec63e07aSXin Li- fclose(fdest); 2157*ec63e07aSXin Li- return fails; 2158*ec63e07aSXin Li- } 2159*ec63e07aSXin Li- 2160*ec63e07aSXin Li- if (triple) { 2161*ec63e07aSXin Li- green = image->comps[1].data; 2162*ec63e07aSXin Li- blue = image->comps[2].data; 2163*ec63e07aSXin Li- for (i = 1; i <= 2; i++) { 2164*ec63e07aSXin Li- if (image->comps[i].data == NULL) { 2165*ec63e07aSXin Li- fprintf(stderr, 2166*ec63e07aSXin Li- "imagetopnm: planes[%d] == NULL.\n", i); 2167*ec63e07aSXin Li- fprintf(stderr, "\tAborting\n"); 2168*ec63e07aSXin Li- fclose(fdest); 2169*ec63e07aSXin Li- return fails; 2170*ec63e07aSXin Li- } 2171*ec63e07aSXin Li- } 2172*ec63e07aSXin Li- } else { 2173*ec63e07aSXin Li- green = blue = NULL; 2174*ec63e07aSXin Li- } 2175*ec63e07aSXin Li- 2176*ec63e07aSXin Li- if (has_alpha) { 2177*ec63e07aSXin Li- const char *tt = (triple ? "RGB_ALPHA" : "GRAYSCALE_ALPHA"); 2178*ec63e07aSXin Li- 2179*ec63e07aSXin Li- fprintf(fdest, "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %u\n" 2180*ec63e07aSXin Li- "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", opj_version(), 2181*ec63e07aSXin Li- wr, hr, ncomp, max, tt); 2182*ec63e07aSXin Li- alpha = image->comps[ncomp - 1].data; 2183*ec63e07aSXin Li- adjustA = (image->comps[ncomp - 1].sgnd ? 2184*ec63e07aSXin Li- 1 << (image->comps[ncomp - 1].prec - 1) : 0); 2185*ec63e07aSXin Li- } else { 2186*ec63e07aSXin Li- fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n", 2187*ec63e07aSXin Li- opj_version(), wr, hr, max); 2188*ec63e07aSXin Li- adjustA = 0; 2189*ec63e07aSXin Li- } 2190*ec63e07aSXin Li- adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); 2191*ec63e07aSXin Li+ /* netpbm: */ 2192*ec63e07aSXin Li+ fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2193*ec63e07aSXin Li 2194*ec63e07aSXin Li if (triple) { 2195*ec63e07aSXin Li- adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); 2196*ec63e07aSXin Li- adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); 2197*ec63e07aSXin Li- } else { 2198*ec63e07aSXin Li- adjustG = adjustB = 0; 2199*ec63e07aSXin Li- } 2200*ec63e07aSXin Li- 2201*ec63e07aSXin Li- for (i = 0; i < wr * hr; ++i) { 2202*ec63e07aSXin Li- if (two) { 2203*ec63e07aSXin Li- v = *red + adjustR; 2204*ec63e07aSXin Li- ++red; 2205*ec63e07aSXin Li- if (v > 65535) { 2206*ec63e07aSXin Li- v = 65535; 2207*ec63e07aSXin Li- } else if (v < 0) { 2208*ec63e07aSXin Li- v = 0; 2209*ec63e07aSXin Li- } 2210*ec63e07aSXin Li- 2211*ec63e07aSXin Li- /* netpbm: */ 2212*ec63e07aSXin Li- fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2213*ec63e07aSXin Li- 2214*ec63e07aSXin Li- if (triple) { 2215*ec63e07aSXin Li- v = *green + adjustG; 2216*ec63e07aSXin Li- ++green; 2217*ec63e07aSXin Li- if (v > 65535) { 2218*ec63e07aSXin Li- v = 65535; 2219*ec63e07aSXin Li- } else if (v < 0) { 2220*ec63e07aSXin Li- v = 0; 2221*ec63e07aSXin Li- } 2222*ec63e07aSXin Li- 2223*ec63e07aSXin Li- /* netpbm: */ 2224*ec63e07aSXin Li- fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2225*ec63e07aSXin Li- 2226*ec63e07aSXin Li- v = *blue + adjustB; 2227*ec63e07aSXin Li- ++blue; 2228*ec63e07aSXin Li- if (v > 65535) { 2229*ec63e07aSXin Li- v = 65535; 2230*ec63e07aSXin Li- } else if (v < 0) { 2231*ec63e07aSXin Li- v = 0; 2232*ec63e07aSXin Li- } 2233*ec63e07aSXin Li- 2234*ec63e07aSXin Li- /* netpbm: */ 2235*ec63e07aSXin Li- fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2236*ec63e07aSXin Li- 2237*ec63e07aSXin Li- }/* if(triple) */ 2238*ec63e07aSXin Li- 2239*ec63e07aSXin Li- if (has_alpha) { 2240*ec63e07aSXin Li- v = *alpha + adjustA; 2241*ec63e07aSXin Li- ++alpha; 2242*ec63e07aSXin Li- if (v > 65535) { 2243*ec63e07aSXin Li- v = 65535; 2244*ec63e07aSXin Li- } else if (v < 0) { 2245*ec63e07aSXin Li- v = 0; 2246*ec63e07aSXin Li- } 2247*ec63e07aSXin Li- 2248*ec63e07aSXin Li- /* netpbm: */ 2249*ec63e07aSXin Li- fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2250*ec63e07aSXin Li- } 2251*ec63e07aSXin Li- continue; 2252*ec63e07aSXin Li- 2253*ec63e07aSXin Li- } /* if(two) */ 2254*ec63e07aSXin Li- 2255*ec63e07aSXin Li- /* prec <= 8: */ 2256*ec63e07aSXin Li- v = *red++; 2257*ec63e07aSXin Li- if (v > 255) { 2258*ec63e07aSXin Li- v = 255; 2259*ec63e07aSXin Li- } else if (v < 0) { 2260*ec63e07aSXin Li- v = 0; 2261*ec63e07aSXin Li- } 2262*ec63e07aSXin Li- 2263*ec63e07aSXin Li- fprintf(fdest, "%c", (unsigned char)v); 2264*ec63e07aSXin Li- if (triple) { 2265*ec63e07aSXin Li- v = *green++; 2266*ec63e07aSXin Li- if (v > 255) { 2267*ec63e07aSXin Li- v = 255; 2268*ec63e07aSXin Li- } else if (v < 0) { 2269*ec63e07aSXin Li- v = 0; 2270*ec63e07aSXin Li- } 2271*ec63e07aSXin Li- 2272*ec63e07aSXin Li- fprintf(fdest, "%c", (unsigned char)v); 2273*ec63e07aSXin Li- v = *blue++; 2274*ec63e07aSXin Li- if (v > 255) { 2275*ec63e07aSXin Li- v = 255; 2276*ec63e07aSXin Li- } else if (v < 0) { 2277*ec63e07aSXin Li- v = 0; 2278*ec63e07aSXin Li- } 2279*ec63e07aSXin Li- 2280*ec63e07aSXin Li- fprintf(fdest, "%c", (unsigned char)v); 2281*ec63e07aSXin Li- } 2282*ec63e07aSXin Li- if (has_alpha) { 2283*ec63e07aSXin Li- v = *alpha++; 2284*ec63e07aSXin Li- if (v > 255) { 2285*ec63e07aSXin Li- v = 255; 2286*ec63e07aSXin Li- } else if (v < 0) { 2287*ec63e07aSXin Li- v = 0; 2288*ec63e07aSXin Li- } 2289*ec63e07aSXin Li- 2290*ec63e07aSXin Li- fprintf(fdest, "%c", (unsigned char)v); 2291*ec63e07aSXin Li- } 2292*ec63e07aSXin Li- } /* for(i */ 2293*ec63e07aSXin Li+ v = *green + adjustG; 2294*ec63e07aSXin Li+ ++green; 2295*ec63e07aSXin Li+ if (v > 65535) { 2296*ec63e07aSXin Li+ v = 65535; 2297*ec63e07aSXin Li+ } else if (v < 0) { 2298*ec63e07aSXin Li+ v = 0; 2299*ec63e07aSXin Li+ } 2300*ec63e07aSXin Li+ 2301*ec63e07aSXin Li+ /* netpbm: */ 2302*ec63e07aSXin Li+ fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2303*ec63e07aSXin Li+ 2304*ec63e07aSXin Li+ v = *blue + adjustB; 2305*ec63e07aSXin Li+ ++blue; 2306*ec63e07aSXin Li+ if (v > 65535) { 2307*ec63e07aSXin Li+ v = 65535; 2308*ec63e07aSXin Li+ } else if (v < 0) { 2309*ec63e07aSXin Li+ v = 0; 2310*ec63e07aSXin Li+ } 2311*ec63e07aSXin Li 2312*ec63e07aSXin Li- fclose(fdest); 2313*ec63e07aSXin Li- return 0; 2314*ec63e07aSXin Li- } 2315*ec63e07aSXin Li+ /* netpbm: */ 2316*ec63e07aSXin Li+ fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2317*ec63e07aSXin Li 2318*ec63e07aSXin Li- /* YUV or MONO: */ 2319*ec63e07aSXin Li+ } /* if(triple) */ 2320*ec63e07aSXin Li 2321*ec63e07aSXin Li- if (image->numcomps > ncomp) { 2322*ec63e07aSXin Li- fprintf(stderr, "WARNING -> [PGM file] Only the first component\n"); 2323*ec63e07aSXin Li- fprintf(stderr, " is written to the file\n"); 2324*ec63e07aSXin Li- } 2325*ec63e07aSXin Li- destname = (char*)malloc(strlen(outfile) + 8); 2326*ec63e07aSXin Li- if (destname == NULL) { 2327*ec63e07aSXin Li- fprintf(stderr, "imagetopnm: memory out\n"); 2328*ec63e07aSXin Li- return 1; 2329*ec63e07aSXin Li- } 2330*ec63e07aSXin Li- for (compno = 0; compno < ncomp; compno++) { 2331*ec63e07aSXin Li- if (ncomp > 1) { 2332*ec63e07aSXin Li- /*sprintf(destname, "%d.%s", compno, outfile);*/ 2333*ec63e07aSXin Li- const size_t olen = strlen(outfile); 2334*ec63e07aSXin Li- const size_t dotpos = olen - 4; 2335*ec63e07aSXin Li- 2336*ec63e07aSXin Li- strncpy(destname, outfile, dotpos); 2337*ec63e07aSXin Li- sprintf(destname + dotpos, "_%u.pgm", compno); 2338*ec63e07aSXin Li- } else { 2339*ec63e07aSXin Li- sprintf(destname, "%s", outfile); 2340*ec63e07aSXin Li- } 2341*ec63e07aSXin Li- 2342*ec63e07aSXin Li- fdest = fopen(destname, "wb"); 2343*ec63e07aSXin Li- if (!fdest) { 2344*ec63e07aSXin Li- fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname); 2345*ec63e07aSXin Li- free(destname); 2346*ec63e07aSXin Li- return 1; 2347*ec63e07aSXin Li- } 2348*ec63e07aSXin Li- wr = (int)image->comps[compno].w; 2349*ec63e07aSXin Li- hr = (int)image->comps[compno].h; 2350*ec63e07aSXin Li- prec = (int)image->comps[compno].prec; 2351*ec63e07aSXin Li- max = (1 << prec) - 1; 2352*ec63e07aSXin Li- 2353*ec63e07aSXin Li- fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n", 2354*ec63e07aSXin Li- opj_version(), wr, hr, max); 2355*ec63e07aSXin Li- 2356*ec63e07aSXin Li- red = image->comps[compno].data; 2357*ec63e07aSXin Li- if (!red) { 2358*ec63e07aSXin Li- fclose(fdest); 2359*ec63e07aSXin Li- continue; 2360*ec63e07aSXin Li- } 2361*ec63e07aSXin Li- 2362*ec63e07aSXin Li- adjustR = 2363*ec63e07aSXin Li- (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); 2364*ec63e07aSXin Li- 2365*ec63e07aSXin Li- if (prec > 8) { 2366*ec63e07aSXin Li- for (i = 0; i < wr * hr; i++) { 2367*ec63e07aSXin Li- v = *red + adjustR; 2368*ec63e07aSXin Li- ++red; 2369*ec63e07aSXin Li- if (v > 65535) { 2370*ec63e07aSXin Li- v = 65535; 2371*ec63e07aSXin Li- } else if (v < 0) { 2372*ec63e07aSXin Li- v = 0; 2373*ec63e07aSXin Li- } 2374*ec63e07aSXin Li- 2375*ec63e07aSXin Li- /* netpbm: */ 2376*ec63e07aSXin Li- fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2377*ec63e07aSXin Li- 2378*ec63e07aSXin Li- if (has_alpha) { 2379*ec63e07aSXin Li- v = *alpha++; 2380*ec63e07aSXin Li- if (v > 65535) { 2381*ec63e07aSXin Li- v = 65535; 2382*ec63e07aSXin Li- } else if (v < 0) { 2383*ec63e07aSXin Li- v = 0; 2384*ec63e07aSXin Li- } 2385*ec63e07aSXin Li- 2386*ec63e07aSXin Li- /* netpbm: */ 2387*ec63e07aSXin Li- fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2388*ec63e07aSXin Li- } 2389*ec63e07aSXin Li- }/* for(i */ 2390*ec63e07aSXin Li- } else { /* prec <= 8 */ 2391*ec63e07aSXin Li- for (i = 0; i < wr * hr; ++i) { 2392*ec63e07aSXin Li- v = *red + adjustR; 2393*ec63e07aSXin Li- ++red; 2394*ec63e07aSXin Li- if (v > 255) { 2395*ec63e07aSXin Li- v = 255; 2396*ec63e07aSXin Li- } else if (v < 0) { 2397*ec63e07aSXin Li- v = 0; 2398*ec63e07aSXin Li- } 2399*ec63e07aSXin Li- 2400*ec63e07aSXin Li- fprintf(fdest, "%c", (unsigned char)v); 2401*ec63e07aSXin Li- } 2402*ec63e07aSXin Li- } 2403*ec63e07aSXin Li- fclose(fdest); 2404*ec63e07aSXin Li- } /* for (compno */ 2405*ec63e07aSXin Li- free(destname); 2406*ec63e07aSXin Li+ if (has_alpha) { 2407*ec63e07aSXin Li+ v = *alpha + adjustA; 2408*ec63e07aSXin Li+ ++alpha; 2409*ec63e07aSXin Li+ if (v > 65535) { 2410*ec63e07aSXin Li+ v = 65535; 2411*ec63e07aSXin Li+ } else if (v < 0) { 2412*ec63e07aSXin Li+ v = 0; 2413*ec63e07aSXin Li+ } 2414*ec63e07aSXin Li+ 2415*ec63e07aSXin Li+ /* netpbm: */ 2416*ec63e07aSXin Li+ fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2417*ec63e07aSXin Li+ } 2418*ec63e07aSXin Li+ continue; 2419*ec63e07aSXin Li+ 2420*ec63e07aSXin Li+ } /* if(two) */ 2421*ec63e07aSXin Li+ 2422*ec63e07aSXin Li+ /* prec <= 8: */ 2423*ec63e07aSXin Li+ v = *red++; 2424*ec63e07aSXin Li+ if (v > 255) { 2425*ec63e07aSXin Li+ v = 255; 2426*ec63e07aSXin Li+ } else if (v < 0) { 2427*ec63e07aSXin Li+ v = 0; 2428*ec63e07aSXin Li+ } 2429*ec63e07aSXin Li+ 2430*ec63e07aSXin Li+ fprintf(fdest, "%c", (unsigned char)v); 2431*ec63e07aSXin Li+ if (triple) { 2432*ec63e07aSXin Li+ v = *green++; 2433*ec63e07aSXin Li+ if (v > 255) { 2434*ec63e07aSXin Li+ v = 255; 2435*ec63e07aSXin Li+ } else if (v < 0) { 2436*ec63e07aSXin Li+ v = 0; 2437*ec63e07aSXin Li+ } 2438*ec63e07aSXin Li+ 2439*ec63e07aSXin Li+ fprintf(fdest, "%c", (unsigned char)v); 2440*ec63e07aSXin Li+ v = *blue++; 2441*ec63e07aSXin Li+ if (v > 255) { 2442*ec63e07aSXin Li+ v = 255; 2443*ec63e07aSXin Li+ } else if (v < 0) { 2444*ec63e07aSXin Li+ v = 0; 2445*ec63e07aSXin Li+ } 2446*ec63e07aSXin Li+ 2447*ec63e07aSXin Li+ fprintf(fdest, "%c", (unsigned char)v); 2448*ec63e07aSXin Li+ } 2449*ec63e07aSXin Li+ if (has_alpha) { 2450*ec63e07aSXin Li+ v = *alpha++; 2451*ec63e07aSXin Li+ if (v > 255) { 2452*ec63e07aSXin Li+ v = 255; 2453*ec63e07aSXin Li+ } else if (v < 0) { 2454*ec63e07aSXin Li+ v = 0; 2455*ec63e07aSXin Li+ } 2456*ec63e07aSXin Li+ 2457*ec63e07aSXin Li+ fprintf(fdest, "%c", (unsigned char)v); 2458*ec63e07aSXin Li+ } 2459*ec63e07aSXin Li+ } /* for(i */ 2460*ec63e07aSXin Li 2461*ec63e07aSXin Li+ fclose(fdest); 2462*ec63e07aSXin Li return 0; 2463*ec63e07aSXin Li-}/* imagetopnm() */ 2464*ec63e07aSXin Li- 2465*ec63e07aSXin Li-/* -->> -->> -->> -->> 2466*ec63e07aSXin Li+ } 2467*ec63e07aSXin Li 2468*ec63e07aSXin Li- RAW IMAGE FORMAT 2469*ec63e07aSXin Li+ /* YUV or MONO: */ 2470*ec63e07aSXin Li 2471*ec63e07aSXin Li- <<-- <<-- <<-- <<-- */ 2472*ec63e07aSXin Li-static opj_image_t* rawtoimage_common(const char *filename, 2473*ec63e07aSXin Li- opj_cparameters_t *parameters, raw_cparameters_t *raw_cp, OPJ_BOOL big_endian) 2474*ec63e07aSXin Li-{ 2475*ec63e07aSXin Li- int subsampling_dx = parameters->subsampling_dx; 2476*ec63e07aSXin Li- int subsampling_dy = parameters->subsampling_dy; 2477*ec63e07aSXin Li- 2478*ec63e07aSXin Li- FILE *f = NULL; 2479*ec63e07aSXin Li- int i, compno, numcomps, w, h; 2480*ec63e07aSXin Li- OPJ_COLOR_SPACE color_space; 2481*ec63e07aSXin Li- opj_image_cmptparm_t *cmptparm; 2482*ec63e07aSXin Li- opj_image_t * image = NULL; 2483*ec63e07aSXin Li- unsigned short ch; 2484*ec63e07aSXin Li- 2485*ec63e07aSXin Li- if ((!(raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & 2486*ec63e07aSXin Li- raw_cp->rawBitDepth)) == 0) { 2487*ec63e07aSXin Li- fprintf(stderr, "\nError: invalid raw image parameters\n"); 2488*ec63e07aSXin Li- fprintf(stderr, "Please use the Format option -F:\n"); 2489*ec63e07aSXin Li- fprintf(stderr, 2490*ec63e07aSXin Li- "-F <width>,<height>,<ncomp>,<bitdepth>,{s,u}@<dx1>x<dy1>:...:<dxn>x<dyn>\n"); 2491*ec63e07aSXin Li- fprintf(stderr, 2492*ec63e07aSXin Li- "If subsampling is omitted, 1x1 is assumed for all components\n"); 2493*ec63e07aSXin Li- fprintf(stderr, 2494*ec63e07aSXin Li- "Example: -i image.raw -o image.j2k -F 512,512,3,8,u@1x1:2x2:2x2\n"); 2495*ec63e07aSXin Li- fprintf(stderr, " for raw 512x512 image with 4:2:0 subsampling\n"); 2496*ec63e07aSXin Li- fprintf(stderr, "Aborting.\n"); 2497*ec63e07aSXin Li- return NULL; 2498*ec63e07aSXin Li- } 2499*ec63e07aSXin Li- 2500*ec63e07aSXin Li- f = fopen(filename, "rb"); 2501*ec63e07aSXin Li- if (!f) { 2502*ec63e07aSXin Li- fprintf(stderr, "Failed to open %s for reading !!\n", filename); 2503*ec63e07aSXin Li- fprintf(stderr, "Aborting\n"); 2504*ec63e07aSXin Li- return NULL; 2505*ec63e07aSXin Li- } 2506*ec63e07aSXin Li- numcomps = raw_cp->rawComp; 2507*ec63e07aSXin Li+ if (image->numcomps > ncomp) { 2508*ec63e07aSXin Li+ fprintf(stderr, "WARNING -> [PGM file] Only the first component\n"); 2509*ec63e07aSXin Li+ fprintf(stderr, " is written to the file\n"); 2510*ec63e07aSXin Li+ } 2511*ec63e07aSXin Li+ destname = (char *)malloc(strlen(outfile) + 8); 2512*ec63e07aSXin Li+ if (destname == NULL) { 2513*ec63e07aSXin Li+ fprintf(stderr, "imagetopnm: memory out\n"); 2514*ec63e07aSXin Li+ return 1; 2515*ec63e07aSXin Li+ } 2516*ec63e07aSXin Li+ for (compno = 0; compno < ncomp; compno++) { 2517*ec63e07aSXin Li+ if (ncomp > 1) { 2518*ec63e07aSXin Li+ /*sprintf(destname, "%d.%s", compno, outfile);*/ 2519*ec63e07aSXin Li+ const size_t olen = strlen(outfile); 2520*ec63e07aSXin Li+ const size_t dotpos = olen - 4; 2521*ec63e07aSXin Li 2522*ec63e07aSXin Li- /* FIXME ADE at this point, tcp_mct has not been properly set in calling function */ 2523*ec63e07aSXin Li- if (numcomps == 1) { 2524*ec63e07aSXin Li- color_space = OPJ_CLRSPC_GRAY; 2525*ec63e07aSXin Li- } else if ((numcomps >= 3) && (parameters->tcp_mct == 0)) { 2526*ec63e07aSXin Li- color_space = OPJ_CLRSPC_SYCC; 2527*ec63e07aSXin Li- } else if ((numcomps >= 3) && (parameters->tcp_mct != 2)) { 2528*ec63e07aSXin Li- color_space = OPJ_CLRSPC_SRGB; 2529*ec63e07aSXin Li+ strncpy(destname, outfile, dotpos); 2530*ec63e07aSXin Li+ sprintf(destname + dotpos, "_%u.pgm", compno); 2531*ec63e07aSXin Li } else { 2532*ec63e07aSXin Li- color_space = OPJ_CLRSPC_UNKNOWN; 2533*ec63e07aSXin Li- } 2534*ec63e07aSXin Li- w = raw_cp->rawWidth; 2535*ec63e07aSXin Li- h = raw_cp->rawHeight; 2536*ec63e07aSXin Li- cmptparm = (opj_image_cmptparm_t*) calloc((OPJ_UINT32)numcomps, 2537*ec63e07aSXin Li- sizeof(opj_image_cmptparm_t)); 2538*ec63e07aSXin Li- if (!cmptparm) { 2539*ec63e07aSXin Li- fprintf(stderr, "Failed to allocate image components parameters !!\n"); 2540*ec63e07aSXin Li- fprintf(stderr, "Aborting\n"); 2541*ec63e07aSXin Li- fclose(f); 2542*ec63e07aSXin Li- return NULL; 2543*ec63e07aSXin Li- } 2544*ec63e07aSXin Li- /* initialize image components */ 2545*ec63e07aSXin Li- for (i = 0; i < numcomps; i++) { 2546*ec63e07aSXin Li- cmptparm[i].prec = (OPJ_UINT32)raw_cp->rawBitDepth; 2547*ec63e07aSXin Li- cmptparm[i].bpp = (OPJ_UINT32)raw_cp->rawBitDepth; 2548*ec63e07aSXin Li- cmptparm[i].sgnd = (OPJ_UINT32)raw_cp->rawSigned; 2549*ec63e07aSXin Li- cmptparm[i].dx = (OPJ_UINT32)(subsampling_dx * raw_cp->rawComps[i].dx); 2550*ec63e07aSXin Li- cmptparm[i].dy = (OPJ_UINT32)(subsampling_dy * raw_cp->rawComps[i].dy); 2551*ec63e07aSXin Li- cmptparm[i].w = (OPJ_UINT32)w; 2552*ec63e07aSXin Li- cmptparm[i].h = (OPJ_UINT32)h; 2553*ec63e07aSXin Li- } 2554*ec63e07aSXin Li- /* create the image */ 2555*ec63e07aSXin Li- image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); 2556*ec63e07aSXin Li- free(cmptparm); 2557*ec63e07aSXin Li- if (!image) { 2558*ec63e07aSXin Li- fclose(f); 2559*ec63e07aSXin Li- return NULL; 2560*ec63e07aSXin Li- } 2561*ec63e07aSXin Li- /* set image offset and reference grid */ 2562*ec63e07aSXin Li- image->x0 = (OPJ_UINT32)parameters->image_offset_x0; 2563*ec63e07aSXin Li- image->y0 = (OPJ_UINT32)parameters->image_offset_y0; 2564*ec63e07aSXin Li- image->x1 = (OPJ_UINT32)parameters->image_offset_x0 + (OPJ_UINT32)(w - 1) * 2565*ec63e07aSXin Li- (OPJ_UINT32)subsampling_dx + 1; 2566*ec63e07aSXin Li- image->y1 = (OPJ_UINT32)parameters->image_offset_y0 + (OPJ_UINT32)(h - 1) * 2567*ec63e07aSXin Li- (OPJ_UINT32)subsampling_dy + 1; 2568*ec63e07aSXin Li- 2569*ec63e07aSXin Li- if (raw_cp->rawBitDepth <= 8) { 2570*ec63e07aSXin Li- unsigned char value = 0; 2571*ec63e07aSXin Li- for (compno = 0; compno < numcomps; compno++) { 2572*ec63e07aSXin Li- int nloop = (w * h) / (raw_cp->rawComps[compno].dx * 2573*ec63e07aSXin Li- raw_cp->rawComps[compno].dy); 2574*ec63e07aSXin Li- for (i = 0; i < nloop; i++) { 2575*ec63e07aSXin Li- if (!fread(&value, 1, 1, f)) { 2576*ec63e07aSXin Li- fprintf(stderr, "Error reading raw file. End of file probably reached.\n"); 2577*ec63e07aSXin Li- opj_image_destroy(image); 2578*ec63e07aSXin Li- fclose(f); 2579*ec63e07aSXin Li- return NULL; 2580*ec63e07aSXin Li- } 2581*ec63e07aSXin Li- image->comps[compno].data[i] = raw_cp->rawSigned ? (char)value : value; 2582*ec63e07aSXin Li- } 2583*ec63e07aSXin Li- } 2584*ec63e07aSXin Li- } else if (raw_cp->rawBitDepth <= 16) { 2585*ec63e07aSXin Li- unsigned short value; 2586*ec63e07aSXin Li- for (compno = 0; compno < numcomps; compno++) { 2587*ec63e07aSXin Li- int nloop = (w * h) / (raw_cp->rawComps[compno].dx * 2588*ec63e07aSXin Li- raw_cp->rawComps[compno].dy); 2589*ec63e07aSXin Li- for (i = 0; i < nloop; i++) { 2590*ec63e07aSXin Li- unsigned char temp1; 2591*ec63e07aSXin Li- unsigned char temp2; 2592*ec63e07aSXin Li- if (!fread(&temp1, 1, 1, f)) { 2593*ec63e07aSXin Li- fprintf(stderr, "Error reading raw file. End of file probably reached.\n"); 2594*ec63e07aSXin Li- opj_image_destroy(image); 2595*ec63e07aSXin Li- fclose(f); 2596*ec63e07aSXin Li- return NULL; 2597*ec63e07aSXin Li- } 2598*ec63e07aSXin Li- if (!fread(&temp2, 1, 1, f)) { 2599*ec63e07aSXin Li- fprintf(stderr, "Error reading raw file. End of file probably reached.\n"); 2600*ec63e07aSXin Li- opj_image_destroy(image); 2601*ec63e07aSXin Li- fclose(f); 2602*ec63e07aSXin Li- return NULL; 2603*ec63e07aSXin Li- } 2604*ec63e07aSXin Li- if (big_endian) { 2605*ec63e07aSXin Li- value = (unsigned short)((temp1 << 8) + temp2); 2606*ec63e07aSXin Li- } else { 2607*ec63e07aSXin Li- value = (unsigned short)((temp2 << 8) + temp1); 2608*ec63e07aSXin Li- } 2609*ec63e07aSXin Li- image->comps[compno].data[i] = raw_cp->rawSigned ? (short)value : value; 2610*ec63e07aSXin Li- } 2611*ec63e07aSXin Li- } 2612*ec63e07aSXin Li- } else { 2613*ec63e07aSXin Li- fprintf(stderr, 2614*ec63e07aSXin Li- "OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n"); 2615*ec63e07aSXin Li- opj_image_destroy(image); 2616*ec63e07aSXin Li- fclose(f); 2617*ec63e07aSXin Li- return NULL; 2618*ec63e07aSXin Li+ sprintf(destname, "%s", outfile); 2619*ec63e07aSXin Li } 2620*ec63e07aSXin Li 2621*ec63e07aSXin Li- if (fread(&ch, 1, 1, f)) { 2622*ec63e07aSXin Li- fprintf(stderr, "Warning. End of raw file not reached... processing anyway\n"); 2623*ec63e07aSXin Li+ fdest = fopen(destname, "wb"); 2624*ec63e07aSXin Li+ if (!fdest) { 2625*ec63e07aSXin Li+ fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname); 2626*ec63e07aSXin Li+ free(destname); 2627*ec63e07aSXin Li+ return 1; 2628*ec63e07aSXin Li } 2629*ec63e07aSXin Li- fclose(f); 2630*ec63e07aSXin Li+ wr = (int)image->comps[compno].w; 2631*ec63e07aSXin Li+ hr = (int)image->comps[compno].h; 2632*ec63e07aSXin Li+ prec = (int)image->comps[compno].prec; 2633*ec63e07aSXin Li+ max = (1 << prec) - 1; 2634*ec63e07aSXin Li 2635*ec63e07aSXin Li- return image; 2636*ec63e07aSXin Li-} 2637*ec63e07aSXin Li+ fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n", opj_version(), wr, hr, max); 2638*ec63e07aSXin Li 2639*ec63e07aSXin Li-opj_image_t* rawltoimage(const char *filename, opj_cparameters_t *parameters, 2640*ec63e07aSXin Li- raw_cparameters_t *raw_cp) 2641*ec63e07aSXin Li-{ 2642*ec63e07aSXin Li- return rawtoimage_common(filename, parameters, raw_cp, OPJ_FALSE); 2643*ec63e07aSXin Li-} 2644*ec63e07aSXin Li- 2645*ec63e07aSXin Li-opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, 2646*ec63e07aSXin Li- raw_cparameters_t *raw_cp) 2647*ec63e07aSXin Li-{ 2648*ec63e07aSXin Li- return rawtoimage_common(filename, parameters, raw_cp, OPJ_TRUE); 2649*ec63e07aSXin Li-} 2650*ec63e07aSXin Li+ red = image->comps[compno].data; 2651*ec63e07aSXin Li 2652*ec63e07aSXin Li-static int imagetoraw_common(opj_image_t * image, const char *outfile, 2653*ec63e07aSXin Li- OPJ_BOOL big_endian) 2654*ec63e07aSXin Li-{ 2655*ec63e07aSXin Li- FILE *rawFile = NULL; 2656*ec63e07aSXin Li- size_t res; 2657*ec63e07aSXin Li- unsigned int compno, numcomps; 2658*ec63e07aSXin Li- int w, h, fails; 2659*ec63e07aSXin Li- int line, row, curr, mask; 2660*ec63e07aSXin Li- int *ptr; 2661*ec63e07aSXin Li- unsigned char uc; 2662*ec63e07aSXin Li- (void)big_endian; 2663*ec63e07aSXin Li- 2664*ec63e07aSXin Li- if ((image->numcomps * image->x1 * image->y1) == 0) { 2665*ec63e07aSXin Li- fprintf(stderr, "\nError: invalid raw image parameters\n"); 2666*ec63e07aSXin Li- return 1; 2667*ec63e07aSXin Li+ if (!red) { 2668*ec63e07aSXin Li+ fclose(fdest); 2669*ec63e07aSXin Li+ continue; 2670*ec63e07aSXin Li } 2671*ec63e07aSXin Li 2672*ec63e07aSXin Li- numcomps = image->numcomps; 2673*ec63e07aSXin Li+ adjustR = 2674*ec63e07aSXin Li+ (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); 2675*ec63e07aSXin Li 2676*ec63e07aSXin Li- if (numcomps > 4) { 2677*ec63e07aSXin Li- numcomps = 4; 2678*ec63e07aSXin Li- } 2679*ec63e07aSXin Li- 2680*ec63e07aSXin Li- for (compno = 1; compno < numcomps; ++compno) { 2681*ec63e07aSXin Li- if (image->comps[0].dx != image->comps[compno].dx) { 2682*ec63e07aSXin Li- break; 2683*ec63e07aSXin Li- } 2684*ec63e07aSXin Li- if (image->comps[0].dy != image->comps[compno].dy) { 2685*ec63e07aSXin Li- break; 2686*ec63e07aSXin Li+ if (prec > 8) { 2687*ec63e07aSXin Li+ for (i = 0; i < wr * hr; i++) { 2688*ec63e07aSXin Li+ v = *red + adjustR; 2689*ec63e07aSXin Li+ ++red; 2690*ec63e07aSXin Li+ if (v > 65535) { 2691*ec63e07aSXin Li+ v = 65535; 2692*ec63e07aSXin Li+ } else if (v < 0) { 2693*ec63e07aSXin Li+ v = 0; 2694*ec63e07aSXin Li } 2695*ec63e07aSXin Li- if (image->comps[0].prec != image->comps[compno].prec) { 2696*ec63e07aSXin Li- break; 2697*ec63e07aSXin Li- } 2698*ec63e07aSXin Li- if (image->comps[0].sgnd != image->comps[compno].sgnd) { 2699*ec63e07aSXin Li- break; 2700*ec63e07aSXin Li- } 2701*ec63e07aSXin Li- } 2702*ec63e07aSXin Li- if (compno != numcomps) { 2703*ec63e07aSXin Li- fprintf(stderr, 2704*ec63e07aSXin Li- "imagetoraw_common: All components shall have the same subsampling, same bit depth, same sign.\n"); 2705*ec63e07aSXin Li- fprintf(stderr, "\tAborting\n"); 2706*ec63e07aSXin Li- return 1; 2707*ec63e07aSXin Li- } 2708*ec63e07aSXin Li 2709*ec63e07aSXin Li- rawFile = fopen(outfile, "wb"); 2710*ec63e07aSXin Li- if (!rawFile) { 2711*ec63e07aSXin Li- fprintf(stderr, "Failed to open %s for writing !!\n", outfile); 2712*ec63e07aSXin Li- return 1; 2713*ec63e07aSXin Li- } 2714*ec63e07aSXin Li- 2715*ec63e07aSXin Li- fails = 1; 2716*ec63e07aSXin Li- fprintf(stdout, "Raw image characteristics: %d components\n", image->numcomps); 2717*ec63e07aSXin Li+ /* netpbm: */ 2718*ec63e07aSXin Li+ fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2719*ec63e07aSXin Li 2720*ec63e07aSXin Li- for (compno = 0; compno < image->numcomps; compno++) { 2721*ec63e07aSXin Li- fprintf(stdout, "Component %u characteristics: %dx%dx%d %s\n", compno, 2722*ec63e07aSXin Li- image->comps[compno].w, 2723*ec63e07aSXin Li- image->comps[compno].h, image->comps[compno].prec, 2724*ec63e07aSXin Li- image->comps[compno].sgnd == 1 ? "signed" : "unsigned"); 2725*ec63e07aSXin Li- 2726*ec63e07aSXin Li- w = (int)image->comps[compno].w; 2727*ec63e07aSXin Li- h = (int)image->comps[compno].h; 2728*ec63e07aSXin Li- 2729*ec63e07aSXin Li- if (image->comps[compno].prec <= 8) { 2730*ec63e07aSXin Li- if (image->comps[compno].sgnd == 1) { 2731*ec63e07aSXin Li- mask = (1 << image->comps[compno].prec) - 1; 2732*ec63e07aSXin Li- ptr = image->comps[compno].data; 2733*ec63e07aSXin Li- for (line = 0; line < h; line++) { 2734*ec63e07aSXin Li- for (row = 0; row < w; row++) { 2735*ec63e07aSXin Li- curr = *ptr; 2736*ec63e07aSXin Li- if (curr > 127) { 2737*ec63e07aSXin Li- curr = 127; 2738*ec63e07aSXin Li- } else if (curr < -128) { 2739*ec63e07aSXin Li- curr = -128; 2740*ec63e07aSXin Li- } 2741*ec63e07aSXin Li- uc = (unsigned char)(curr & mask); 2742*ec63e07aSXin Li- res = fwrite(&uc, 1, 1, rawFile); 2743*ec63e07aSXin Li- if (res < 1) { 2744*ec63e07aSXin Li- fprintf(stderr, "failed to write 1 byte for %s\n", outfile); 2745*ec63e07aSXin Li- goto fin; 2746*ec63e07aSXin Li- } 2747*ec63e07aSXin Li- ptr++; 2748*ec63e07aSXin Li- } 2749*ec63e07aSXin Li- } 2750*ec63e07aSXin Li- } else if (image->comps[compno].sgnd == 0) { 2751*ec63e07aSXin Li- mask = (1 << image->comps[compno].prec) - 1; 2752*ec63e07aSXin Li- ptr = image->comps[compno].data; 2753*ec63e07aSXin Li- for (line = 0; line < h; line++) { 2754*ec63e07aSXin Li- for (row = 0; row < w; row++) { 2755*ec63e07aSXin Li- curr = *ptr; 2756*ec63e07aSXin Li- if (curr > 255) { 2757*ec63e07aSXin Li- curr = 255; 2758*ec63e07aSXin Li- } else if (curr < 0) { 2759*ec63e07aSXin Li- curr = 0; 2760*ec63e07aSXin Li- } 2761*ec63e07aSXin Li- uc = (unsigned char)(curr & mask); 2762*ec63e07aSXin Li- res = fwrite(&uc, 1, 1, rawFile); 2763*ec63e07aSXin Li- if (res < 1) { 2764*ec63e07aSXin Li- fprintf(stderr, "failed to write 1 byte for %s\n", outfile); 2765*ec63e07aSXin Li- goto fin; 2766*ec63e07aSXin Li- } 2767*ec63e07aSXin Li- ptr++; 2768*ec63e07aSXin Li- } 2769*ec63e07aSXin Li- } 2770*ec63e07aSXin Li- } 2771*ec63e07aSXin Li- } else if (image->comps[compno].prec <= 16) { 2772*ec63e07aSXin Li- if (image->comps[compno].sgnd == 1) { 2773*ec63e07aSXin Li- union { 2774*ec63e07aSXin Li- signed short val; 2775*ec63e07aSXin Li- signed char vals[2]; 2776*ec63e07aSXin Li- } uc16; 2777*ec63e07aSXin Li- mask = (1 << image->comps[compno].prec) - 1; 2778*ec63e07aSXin Li- ptr = image->comps[compno].data; 2779*ec63e07aSXin Li- for (line = 0; line < h; line++) { 2780*ec63e07aSXin Li- for (row = 0; row < w; row++) { 2781*ec63e07aSXin Li- curr = *ptr; 2782*ec63e07aSXin Li- if (curr > 32767) { 2783*ec63e07aSXin Li- curr = 32767; 2784*ec63e07aSXin Li- } else if (curr < -32768) { 2785*ec63e07aSXin Li- curr = -32768; 2786*ec63e07aSXin Li- } 2787*ec63e07aSXin Li- uc16.val = (signed short)(curr & mask); 2788*ec63e07aSXin Li- res = fwrite(uc16.vals, 1, 2, rawFile); 2789*ec63e07aSXin Li- if (res < 2) { 2790*ec63e07aSXin Li- fprintf(stderr, "failed to write 2 byte for %s\n", outfile); 2791*ec63e07aSXin Li- goto fin; 2792*ec63e07aSXin Li- } 2793*ec63e07aSXin Li- ptr++; 2794*ec63e07aSXin Li- } 2795*ec63e07aSXin Li- } 2796*ec63e07aSXin Li- } else if (image->comps[compno].sgnd == 0) { 2797*ec63e07aSXin Li- union { 2798*ec63e07aSXin Li- unsigned short val; 2799*ec63e07aSXin Li- unsigned char vals[2]; 2800*ec63e07aSXin Li- } uc16; 2801*ec63e07aSXin Li- mask = (1 << image->comps[compno].prec) - 1; 2802*ec63e07aSXin Li- ptr = image->comps[compno].data; 2803*ec63e07aSXin Li- for (line = 0; line < h; line++) { 2804*ec63e07aSXin Li- for (row = 0; row < w; row++) { 2805*ec63e07aSXin Li- curr = *ptr; 2806*ec63e07aSXin Li- if (curr > 65535) { 2807*ec63e07aSXin Li- curr = 65535; 2808*ec63e07aSXin Li- } else if (curr < 0) { 2809*ec63e07aSXin Li- curr = 0; 2810*ec63e07aSXin Li- } 2811*ec63e07aSXin Li- uc16.val = (unsigned short)(curr & mask); 2812*ec63e07aSXin Li- res = fwrite(uc16.vals, 1, 2, rawFile); 2813*ec63e07aSXin Li- if (res < 2) { 2814*ec63e07aSXin Li- fprintf(stderr, "failed to write 2 byte for %s\n", outfile); 2815*ec63e07aSXin Li- goto fin; 2816*ec63e07aSXin Li- } 2817*ec63e07aSXin Li- ptr++; 2818*ec63e07aSXin Li- } 2819*ec63e07aSXin Li- } 2820*ec63e07aSXin Li- } 2821*ec63e07aSXin Li- } else if (image->comps[compno].prec <= 32) { 2822*ec63e07aSXin Li- fprintf(stderr, "More than 16 bits per component not handled yet\n"); 2823*ec63e07aSXin Li- goto fin; 2824*ec63e07aSXin Li- } else { 2825*ec63e07aSXin Li- fprintf(stderr, "Error: invalid precision: %d\n", image->comps[compno].prec); 2826*ec63e07aSXin Li- goto fin; 2827*ec63e07aSXin Li+ if (has_alpha) { 2828*ec63e07aSXin Li+ v = *alpha++; 2829*ec63e07aSXin Li+ if (v > 65535) { 2830*ec63e07aSXin Li+ v = 65535; 2831*ec63e07aSXin Li+ } else if (v < 0) { 2832*ec63e07aSXin Li+ v = 0; 2833*ec63e07aSXin Li+ } 2834*ec63e07aSXin Li+ 2835*ec63e07aSXin Li+ /* netpbm: */ 2836*ec63e07aSXin Li+ fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v); 2837*ec63e07aSXin Li+ } 2838*ec63e07aSXin Li+ } /* for(i */ 2839*ec63e07aSXin Li+ } else { /* prec <= 8 */ 2840*ec63e07aSXin Li+ for (i = 0; i < wr * hr; ++i) { 2841*ec63e07aSXin Li+ v = *red + adjustR; 2842*ec63e07aSXin Li+ ++red; 2843*ec63e07aSXin Li+ if (v > 255) { 2844*ec63e07aSXin Li+ v = 255; 2845*ec63e07aSXin Li+ } else if (v < 0) { 2846*ec63e07aSXin Li+ v = 0; 2847*ec63e07aSXin Li } 2848*ec63e07aSXin Li+ fprintf(fdest, "%c", (unsigned char)v); 2849*ec63e07aSXin Li+ } 2850*ec63e07aSXin Li } 2851*ec63e07aSXin Li- fails = 0; 2852*ec63e07aSXin Li-fin: 2853*ec63e07aSXin Li- fclose(rawFile); 2854*ec63e07aSXin Li- return fails; 2855*ec63e07aSXin Li-} 2856*ec63e07aSXin Li- 2857*ec63e07aSXin Li-int imagetoraw(opj_image_t * image, const char *outfile) 2858*ec63e07aSXin Li-{ 2859*ec63e07aSXin Li- return imagetoraw_common(image, outfile, OPJ_TRUE); 2860*ec63e07aSXin Li-} 2861*ec63e07aSXin Li- 2862*ec63e07aSXin Li-int imagetorawl(opj_image_t * image, const char *outfile) 2863*ec63e07aSXin Li-{ 2864*ec63e07aSXin Li- return imagetoraw_common(image, outfile, OPJ_FALSE); 2865*ec63e07aSXin Li-} 2866*ec63e07aSXin Li+ fclose(fdest); 2867*ec63e07aSXin Li+ } /* for (compno */ 2868*ec63e07aSXin Li+ free(destname); 2869*ec63e07aSXin Li 2870*ec63e07aSXin Li+ return 0; 2871*ec63e07aSXin Li+} /* imagetopnm() */ 2872