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