-/*\r
- * Copyright (c) 2001-2003, David Janssens\r
- * Copyright (c) 2002-2003, Yannick Verschueren\r
- * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe\r
- * Copyright (c) 2005, Herve Drolon, FreeImage Team\r
- * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
- * Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifdef USE_JPWL\r
-\r
-#include "crc.h"\r
-\r
-/**\r
-@file crc.c\r
-@brief Functions used to compute the 16- and 32-bit CRC of byte arrays\r
-\r
-*/\r
-\r
-/** file: CRC16.CPP\r
- *\r
- * CRC - Cyclic Redundancy Check (16-bit)\r
- *\r
- * A CRC-checksum is used to be sure, the data hasn't changed or is false.\r
- * To create a CRC-checksum, initialise a check-variable (unsigned short),\r
- * and set this to zero. Than call for every byte in the file (e.g.) the\r
- * procedure updateCRC16 with this check-variable as the first parameter,\r
- * and the byte as the second. At the end, the check-variable contains the\r
- * CRC-checksum.\r
- *\r
- * implemented by Michael Neumann, 14.06.1998\r
- * \r
- */\r
-const unsigned short CRC16_table[256] = {\r
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, \r
- 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, \r
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, \r
- 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,\r
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, \r
- 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, \r
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, \r
- 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, \r
- 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, \r
- 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, \r
- 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, \r
- 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,\r
- 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, \r
- 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, \r
- 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, \r
- 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, \r
- 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, \r
- 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,\r
- 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, \r
- 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, \r
- 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,\r
- 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, \r
- 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, \r
- 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, \r
- 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, \r
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, \r
- 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, \r
- 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, \r
- 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, \r
- 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, \r
- 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, \r
- 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0\r
-};\r
-\r
-void updateCRC16(unsigned short *crc, unsigned char data) {\r
- *crc = CRC16_table[(*crc >> 8) & 0xFF] ^ (*crc << 8) ^ data;\r
-};\r
-\r
-\r
-/** file: CRC32.CPP\r
- *\r
- * CRC - Cyclic Redundancy Check (32-bit)\r
- *\r
- * A CRC-checksum is used to be sure, the data hasn't changed or is false.\r
- * To create a CRC-checksum, initialise a check-variable (unsigned long),\r
- * and set this to zero. Than call for every byte in the file (e.g.) the\r
- * procedure updateCRC32 with this check-variable as the first parameter,\r
- * and the byte as the second. At the end, the check-variable contains the\r
- * CRC-checksum.\r
- *\r
- * implemented by Michael Neumann, 14.06.1998\r
- *\r
- */\r
-const unsigned long CRC32_table[256] = {\r
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,\r
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,\r
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,\r
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\r
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\r
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,\r
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,\r
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\r
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,\r
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\r
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,\r
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\r
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,\r
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,\r
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\r
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\r
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,\r
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,\r
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,\r
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\r
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,\r
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,\r
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,\r
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\r
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\r
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,\r
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,\r
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\r
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,\r
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\r
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,\r
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\r
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,\r
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,\r
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\r
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\r
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,\r
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,\r
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,\r
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\r
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,\r
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,\r
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d\r
-};\r
-\r
-void updateCRC32(unsigned long *crc, unsigned char data) {\r
- *crc = CRC32_table[(unsigned char) *crc ^ data] ^ ((*crc >> 8) & 0x00FFFFFF);\r
-};\r
-\r
-#endif /* USE_JPWL */\r
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef USE_JPWL
+
+#include "crc.h"
+
+/**
+@file crc.c
+@brief Functions used to compute the 16- and 32-bit CRC of byte arrays
+
+*/
+
+/** file: CRC16.CPP
+ *
+ * CRC - Cyclic Redundancy Check (16-bit)
+ *
+ * A CRC-checksum is used to be sure, the data hasn't changed or is false.
+ * To create a CRC-checksum, initialise a check-variable (unsigned short),
+ * and set this to zero. Than call for every byte in the file (e.g.) the
+ * procedure updateCRC16 with this check-variable as the first parameter,
+ * and the byte as the second. At the end, the check-variable contains the
+ * CRC-checksum.
+ *
+ * implemented by Michael Neumann, 14.06.1998
+ *
+ */
+const unsigned short CRC16_table[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+void updateCRC16(unsigned short *crc, unsigned char data) {
+ *crc = CRC16_table[(*crc >> 8) & 0xFF] ^ (*crc << 8) ^ data;
+};
+
+
+/** file: CRC32.CPP
+ *
+ * CRC - Cyclic Redundancy Check (32-bit)
+ *
+ * A CRC-checksum is used to be sure, the data hasn't changed or is false.
+ * To create a CRC-checksum, initialise a check-variable (unsigned long),
+ * and set this to zero. Than call for every byte in the file (e.g.) the
+ * procedure updateCRC32 with this check-variable as the first parameter,
+ * and the byte as the second. At the end, the check-variable contains the
+ * CRC-checksum.
+ *
+ * implemented by Michael Neumann, 14.06.1998
+ *
+ */
+const unsigned long CRC32_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+void updateCRC32(unsigned long *crc, unsigned char data) {
+ *crc = CRC32_table[(unsigned char) *crc ^ data] ^ ((*crc >> 8) & 0x00FFFFFF);
+};
+
+#endif /* USE_JPWL */
-/*\r
- * Copyright (c) 2001-2003, David Janssens\r
- * Copyright (c) 2002-2003, Yannick Verschueren\r
- * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe\r
- * Copyright (c) 2005, Herve Drolon, FreeImage Team\r
- * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
- * Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include "opj_includes.h"\r
-\r
-#ifdef USE_JPWL\r
-\r
-/** @defgroup JPWL JPWL - JPEG-2000 Part11 (JPWL) codestream manager */\r
-/*@{*/\r
-\r
-/** @name Local static variables */\r
-/*@{*/\r
-\r
-/** number of JPWL prepared markers */\r
-static int jwmarker_num;\r
-/** properties of JPWL markers to insert */\r
-static jpwl_marker_t jwmarker[JPWL_MAX_NO_MARKERS]; \r
-\r
-/*@}*/\r
-\r
-/*@}*/\r
-\r
-/** @name Local static functions */\r
-/*@{*/\r
-\r
-/** create an EPC marker segment\r
-@param j2k J2K compressor handle\r
-@param esd_on true if ESD is activated\r
-@param red_on true if RED is activated\r
-@param epb_on true if EPB is activated\r
-@param info_on true if informative techniques are activated\r
-@return returns the freshly created EPC\r
-*/\r
-jpwl_epc_ms_t *jpwl_epc_create(opj_j2k_t *j2k, opj_bool esd_on, opj_bool red_on, opj_bool epb_on, opj_bool info_on);\r
-\r
-/*@}*/\r
-\r
-/** create an EPC marker segment\r
-@param j2k J2K compressor handle\r
-@param comps considered component (-1=average, 0/1/2/...=component no.)\r
-@param addrm addressing mode (0=packet, 1=byte range, 2=packet range, 3=reserved)\r
-@param ad_size size of addresses (2/4 bytes)\r
-@param senst sensitivity type\r
-@param se_size sensitivity values size (1/2 bytes)\r
-@param tileno tile where this ESD lies (-1 means MH)\r
-@param svalnum number of sensitivity values (if 0, they will be automatically filled)\r
-@param sensval pointer to an array of sensitivity values (if NULL, they will be automatically filled)\r
-@return returns the freshly created ESD\r
-*/\r
-jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comps, \r
- unsigned char addrm, unsigned char ad_size,\r
- unsigned char senst, int se_size, int tileno,\r
- unsigned long int svalnum, void *sensval);\r
- \r
-/** this function is used to compare two JPWL markers based on\r
-their relevant wishlist position\r
-@param arg1 pointer to first marker\r
-@param arg2 pointer to second marker\r
-@return 1 if arg1>arg2, 0 if arg1=arg2, -1 if arg1<arg2\r
-*/\r
-int jpwl_markcomp(const void *arg1, const void *arg2);\r
-\r
-/** write an EPB MS to a buffer\r
-@param j2k J2K compressor handle\r
-@param epbmark pointer to the EPB MS\r
-@param buf pointer to the memory buffer\r
-*/\r
-void jpwl_epb_write(opj_j2k_t *j2k, jpwl_epb_ms_t *epbmark, unsigned char *buf);\r
-\r
-/** write an EPC MS to a buffer\r
-@param j2k J2K compressor handle\r
-@param epcmark pointer to the EPC MS\r
-@param buf pointer to the memory buffer\r
-*/\r
-void jpwl_epc_write(opj_j2k_t *j2k, jpwl_epc_ms_t *epcmark, unsigned char *buf);\r
-\r
-/** write an ESD MS to a buffer\r
-@param j2k J2K compressor handle\r
-@param esdmark pointer to the ESD MS\r
-@param buf pointer to the memory buffer\r
-*/\r
-void jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esdmark, unsigned char *buf);\r
-\r
-/*-----------------------------------------------------------------*/\r
-\r
-void jpwl_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {\r
-\r
- int mm;\r
-\r
- /* let's reset some settings */\r
-\r
- /* clear the existing markers */\r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
-\r
- switch (jwmarker[mm].id) {\r
-\r
- case J2K_MS_EPB:\r
- opj_free(jwmarker[mm].m.epbmark);\r
- break;\r
-\r
- case J2K_MS_EPC:\r
- opj_free(jwmarker[mm].m.epcmark);\r
- break;\r
-\r
- case J2K_MS_ESD:\r
- opj_free(jwmarker[mm].m.esdmark);\r
- break;\r
-\r
- case J2K_MS_RED:\r
- opj_free(jwmarker[mm].m.redmark);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- /* clear the marker structure array */\r
- memset(jwmarker, 0, sizeof(jpwl_marker_t) * JPWL_MAX_NO_MARKERS);\r
-\r
- /* no more markers in the list */\r
- jwmarker_num = 0;\r
-\r
- /* let's begin creating a marker list, according to user wishes */\r
- jpwl_prepare_marks(j2k, cio, image);\r
-\r
- /* now we dump the JPWL markers on the codestream */\r
- jpwl_dump_marks(j2k, cio, image);\r
-\r
- /* do not know exactly what is this for,\r
- but it gets called during index creation */\r
- j2k->pos_correction = 0;\r
-\r
-}\r
-\r
-void j2k_add_marker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {\r
-\r
- if (!cstr_info)\r
- return;\r
-\r
- /* expand the list? */\r
- if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {\r
- cstr_info->maxmarknum += 100;\r
- cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum * sizeof(opj_marker_info_t));\r
- }\r
-\r
- /* add the marker */\r
- cstr_info->marker[cstr_info->marknum].type = type;\r
- cstr_info->marker[cstr_info->marknum].pos = pos;\r
- cstr_info->marker[cstr_info->marknum].len = len;\r
- cstr_info->marknum++;\r
-\r
-}\r
-\r
-void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {\r
-\r
- unsigned short int socsiz_len = 0;\r
- int ciopos = cio_tell(cio), soc_pos = j2k->cstr_info->main_head_start;\r
- unsigned char *socp = NULL;\r
-\r
- int tileno, acc_tpno, tpno, tilespec, hprot, sens, pprot, packspec, lastileno, packno;\r
-\r
- jpwl_epb_ms_t *epb_mark;\r
- jpwl_epc_ms_t *epc_mark;\r
- jpwl_esd_ms_t *esd_mark;\r
- (void)image;\r
-\r
- /* find (SOC + SIZ) length */\r
- /* I assume SIZ is always the first marker after SOC */\r
- cio_seek(cio, soc_pos + 4);\r
- socsiz_len = (unsigned short int) cio_read(cio, 2) + 4; /* add the 2 marks length itself */\r
- cio_seek(cio, soc_pos + 0);\r
- socp = cio_getbp(cio); /* pointer to SOC */\r
-\r
- /* \r
- EPC MS for Main Header: if we are here it's required\r
- */\r
- /* create the EPC */\r
- if ((epc_mark = jpwl_epc_create(\r
- j2k,\r
- j2k->cp->esd_on, /* is ESD present? */\r
- j2k->cp->red_on, /* is RED present? */\r
- j2k->cp->epb_on, /* is EPB present? */\r
- OPJ_FALSE /* are informative techniques present? */\r
- ))) {\r
-\r
- /* Add this marker to the 'insertanda' list */\r
- if (epc_mark) {\r
- jwmarker[jwmarker_num].id = J2K_MS_EPC; /* its type */\r
- jwmarker[jwmarker_num].m.epcmark = epc_mark; /* the EPC */\r
- jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */\r
- jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.1; /* not so first */\r
- jwmarker[jwmarker_num].len = epc_mark->Lepc; /* its length */\r
- jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].parms_ready = OPJ_FALSE; /* not ready */\r
- jwmarker[jwmarker_num].data_ready = OPJ_TRUE; /* ready */\r
- jwmarker_num++;\r
- };\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "MH EPC : setting %s%s%s\n",\r
- j2k->cp->esd_on ? "ESD, " : "",\r
- j2k->cp->red_on ? "RED, " : "",\r
- j2k->cp->epb_on ? "EPB, " : ""\r
- );\r
-\r
- } else {\r
- /* ooops, problems */\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPC\n"); \r
- };\r
-\r
- /* \r
- ESD MS for Main Header\r
- */\r
- /* first of all, must MH have an ESD MS? */\r
- if (j2k->cp->esd_on && (j2k->cp->sens_MH >= 0)) {\r
-\r
- /* Create the ESD */\r
- if ((esd_mark = jpwl_esd_create(\r
- j2k, /* this encoder handle */\r
- -1, /* we are averaging over all components */\r
- (unsigned char) j2k->cp->sens_range, /* range method */\r
- (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing */\r
- (unsigned char) j2k->cp->sens_MH, /* sensitivity method */\r
- j2k->cp->sens_size, /* sensitivity size */\r
- -1, /* this ESD is in main header */\r
- 0 /*j2k->cstr_info->num*/, /* number of packets in codestream */\r
- NULL /*sensval*/ /* pointer to sensitivity data of packets */\r
- ))) {\r
- \r
- /* Add this marker to the 'insertanda' list */\r
- if (jwmarker_num < JPWL_MAX_NO_MARKERS) {\r
- jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */\r
- jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */\r
- jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* we choose to place it after SIZ */\r
- jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */\r
- jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */\r
- jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* not ready, yet */\r
- jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* not ready */\r
- jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */\r
- jwmarker_num++;\r
- }\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "MH ESDs: method %d\n",\r
- j2k->cp->sens_MH\r
- );\r
-\r
- } else {\r
- /* ooops, problems */\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH ESD\n"); \r
- };\r
-\r
- }\r
-\r
- /* \r
- ESD MSs for Tile Part Headers \r
- */\r
- /* cycle through tiles */\r
- sens = -1; /* default spec: no ESD */\r
- tilespec = 0; /* first tile spec */\r
- acc_tpno = 0;\r
- for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "Tile %d has %d tile part(s)\n",\r
- tileno, j2k->cstr_info->tile[tileno].num_tps\r
- );\r
-\r
- /* for every tile part in the tile */\r
- for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {\r
- \r
- int sot_len, Psot, Psotp, mm;\r
- unsigned long sot_pos, post_sod_pos;\r
-\r
- unsigned long int left_THmarks_len;\r
-\r
- /******* sot_pos = j2k->cstr_info->tile[tileno].start_pos; */\r
- sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;\r
- cio_seek(cio, sot_pos + 2); \r
- sot_len = cio_read(cio, 2); /* SOT Len */\r
- cio_skip(cio, 2);\r
- Psotp = cio_tell(cio);\r
- Psot = cio_read(cio, 4); /* tile length */\r
-\r
- /******* post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */\r
- post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;\r
- left_THmarks_len = post_sod_pos - sot_pos;\r
-\r
- /* add all the lengths of the markers which are len-ready and stay within SOT and SOD */\r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
- if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {\r
- if (jwmarker[mm].len_ready)\r
- left_THmarks_len += jwmarker[mm].len + 2;\r
- else {\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",\r
- jwmarker[mm].id, jwmarker[mm].dpos); \r
- exit(1);\r
- }\r
- }\r
- }\r
-\r
- /******* if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == tileno)) */\r
- if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == acc_tpno))\r
- /* we got a specification from this tile onwards */\r
- sens = j2k->cp->sens_TPH[tilespec++];\r
- \r
- /* must this TPH have an ESD MS? */\r
- if (j2k->cp->esd_on && (sens >= 0)) {\r
-\r
- /* Create the ESD */\r
- if ((esd_mark = jpwl_esd_create(\r
- j2k, /* this encoder handle */\r
- -1, /* we are averaging over all components */\r
- (unsigned char) j2k->cp->sens_range, /* range method */\r
- (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing size */\r
- (unsigned char) sens, /* sensitivity method */\r
- j2k->cp->sens_size, /* sensitivity value size */\r
- tileno, /* this ESD is in a tile */\r
- 0, /* number of packets in codestream */\r
- NULL /* pointer to sensitivity data of packets */\r
- ))) {\r
- \r
- /* Add this marker to the 'insertanda' list */\r
- if (jwmarker_num < JPWL_MAX_NO_MARKERS) {\r
- jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */\r
- jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */\r
- /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */\r
- jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */\r
- jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */\r
- jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */\r
- jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready, yet */\r
- jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* not ready */\r
- jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* ready */\r
- jwmarker_num++;\r
- }\r
-\r
- /* update Psot of the tile */\r
- cio_seek(cio, Psotp);\r
- cio_write(cio, Psot + esd_mark->Lesd + 2, 4);\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- /******* "TPH ESDs: tile %02d, method %d\n", */\r
- "TPH ESDs: tile %02d, part %02d, method %d\n",\r
- /******* tileno, */\r
- tileno, tpno,\r
- sens\r
- );\r
-\r
- } else {\r
- /* ooops, problems */\r
- /***** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d\n", tileno); */\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d,%d\n", tileno, tpno);\r
- };\r
-\r
- }\r
- \r
- }\r
- \r
- };\r
-\r
- /* \r
- EPB MS for Main Header\r
- */\r
- /* first of all, must MH have an EPB MS? */\r
- if (j2k->cp->epb_on && (j2k->cp->hprot_MH > 0)) {\r
-\r
- int mm;\r
-\r
- /* position of SOT */\r
- unsigned int sot_pos = j2k->cstr_info->main_head_end + 1;\r
-\r
- /* how much space is there between end of SIZ and beginning of SOT? */\r
- int left_MHmarks_len = sot_pos - socsiz_len;\r
-\r
- /* add all the lengths of the markers which are len-ready and stay within SOC and SOT */\r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
- if ( jwmarker[mm].pos < sot_pos) { /* jwmarker[mm].pos >=0 since ulong */\r
- if (jwmarker[mm].len_ready)\r
- left_MHmarks_len += jwmarker[mm].len + 2;\r
- else {\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up MH EPB\n",\r
- jwmarker[mm].id, jwmarker[mm].dpos); \r
- exit(1);\r
- }\r
- }\r
- }\r
-\r
- /* Create the EPB */\r
- if ((epb_mark = jpwl_epb_create(\r
- j2k, /* this encoder handle */\r
- OPJ_TRUE, /* is it the latest? */\r
- OPJ_TRUE, /* is it packed? not for now */\r
- -1, /* we are in main header */\r
- 0, /* its index is 0 (first) */\r
- j2k->cp->hprot_MH, /* protection type parameters of data */\r
- socsiz_len, /* pre-data: only SOC+SIZ */\r
- left_MHmarks_len /* post-data: from SOC to SOT, and all JPWL markers within */\r
- ))) {\r
- \r
- /* Add this marker to the 'insertanda' list */\r
- if (jwmarker_num < JPWL_MAX_NO_MARKERS) {\r
- jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */\r
- jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */\r
- jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */\r
- jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */\r
- jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */\r
- jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */\r
- jwmarker_num++;\r
- }\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "MH EPB : prot. %d\n",\r
- j2k->cp->hprot_MH\r
- );\r
-\r
- } else {\r
- /* ooops, problems */\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPB\n"); \r
- };\r
- }\r
-\r
- /* \r
- EPB MSs for Tile Parts\r
- */\r
- /* cycle through TPHs */\r
- hprot = j2k->cp->hprot_MH; /* default spec */\r
- tilespec = 0; /* first tile spec */\r
- lastileno = 0;\r
- packspec = 0;\r
- pprot = -1;\r
- acc_tpno = 0;\r
- for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "Tile %d has %d tile part(s)\n",\r
- tileno, j2k->cstr_info->tile[tileno].num_tps\r
- );\r
-\r
- /* for every tile part in the tile */\r
- for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) { \r
- \r
- int sot_len, Psot, Psotp, mm, epb_index = 0, prot_len = 0;\r
- unsigned long sot_pos, post_sod_pos;\r
- unsigned long int left_THmarks_len/*, epbs_len = 0*/;\r
- int startpack = 0, stoppack = j2k->cstr_info->packno;\r
- int first_tp_pack, last_tp_pack;\r
- jpwl_epb_ms_t *tph_epb = NULL;\r
-\r
- /****** sot_pos = j2k->cstr_info->tile[tileno].start_pos; */\r
- sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;\r
- cio_seek(cio, sot_pos + 2); \r
- sot_len = cio_read(cio, 2); /* SOT Len */\r
- cio_skip(cio, 2);\r
- Psotp = cio_tell(cio);\r
- Psot = cio_read(cio, 4); /* tile length */\r
-\r
- /* a-priori length of the data dwelling between SOT and SOD */\r
- /****** post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */\r
- post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;\r
- left_THmarks_len = post_sod_pos - (sot_pos + sot_len + 2);\r
-\r
- /* add all the lengths of the JPWL markers which are len-ready and stay within SOT and SOD */\r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
- if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {\r
- if (jwmarker[mm].len_ready)\r
- left_THmarks_len += jwmarker[mm].len + 2;\r
- else {\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",\r
- jwmarker[mm].id, jwmarker[mm].dpos); \r
- exit(1);\r
- }\r
- }\r
- }\r
-\r
- /****** if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == tileno)) */\r
- if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == acc_tpno))\r
- /* we got a specification from this tile part onwards */\r
- hprot = j2k->cp->hprot_TPH[tilespec++];\r
- \r
- /* must this TPH have an EPB MS? */\r
- if (j2k->cp->epb_on && (hprot > 0)) {\r
-\r
- /* Create the EPB */\r
- if ((epb_mark = jpwl_epb_create(\r
- j2k, /* this encoder handle */\r
- OPJ_FALSE, /* is it the latest? in TPH, no for now (if huge data size in TPH, we'd need more) */\r
- OPJ_TRUE, /* is it packed? yes for now */\r
- tileno, /* we are in TPH */\r
- epb_index++, /* its index is 0 (first) */\r
- hprot, /* protection type parameters of following data */\r
- sot_len + 2, /* pre-data length: only SOT */\r
- left_THmarks_len /* post-data length: from SOT end to SOD inclusive */\r
- ))) {\r
- \r
- /* Add this marker to the 'insertanda' list */\r
- if (jwmarker_num < JPWL_MAX_NO_MARKERS) {\r
- jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */\r
- jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */\r
- /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */\r
- jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */\r
- jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */\r
- jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */\r
- jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* ready */\r
- jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */\r
- jwmarker_num++;\r
- }\r
-\r
- /* update Psot of the tile */\r
- Psot += epb_mark->Lepb + 2;\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- /***** "TPH EPB : tile %02d, prot. %d\n", */\r
- "TPH EPB : tile %02d, part %02d, prot. %d\n",\r
- /***** tileno, */\r
- tileno, tpno,\r
- hprot\r
- );\r
-\r
- /* save this TPH EPB address */\r
- tph_epb = epb_mark;\r
-\r
- } else {\r
- /* ooops, problems */\r
- /****** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB #%d\n", tileno); */\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB in #%d,d\n", tileno, tpno);\r
- };\r
-\r
- } \r
- \r
- startpack = 0;\r
- /* EPB MSs for UEP packet data protection in Tile Parts */\r
- /****** for (packno = 0; packno < j2k->cstr_info->num; packno++) { */\r
- /*first_tp_pack = (tpno > 0) ? (first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno - 1].tp_numpacks) : 0;*/\r
- first_tp_pack = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pack;\r
- last_tp_pack = first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks - 1;\r
- for (packno = 0; packno < j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks; packno++) {\r
-\r
- /******** if ((packspec < JPWL_MAX_NO_PACKSPECS) &&\r
- (j2k->cp->pprot_tileno[packspec] == tileno) && (j2k->cp->pprot_packno[packspec] == packno)) { */\r
- if ((packspec < JPWL_MAX_NO_PACKSPECS) &&\r
- (j2k->cp->pprot_tileno[packspec] == acc_tpno) && (j2k->cp->pprot_packno[packspec] == packno)) {\r
-\r
- /* we got a specification from this tile and packet onwards */\r
- /* print the previous spec */\r
- if (packno > 0) {\r
- stoppack = packno - 1; \r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- /***** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */\r
- "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",\r
- /***** tileno, */\r
- tileno, tpno,\r
- startpack,\r
- stoppack,\r
- /***** j2k->cstr_info->tile[tileno].packet[startpack].start_pos, */\r
- j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,\r
- /***** j2k->cstr_info->tile[tileno].packet[stoppack].end_pos, */\r
- j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,\r
- pprot);\r
-\r
- /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -\r
- j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */\r
- prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -\r
- j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;\r
-\r
- /*\r
- particular case: if this is the last header and the last packet,\r
- then it is better to protect even the EOC marker\r
- */\r
- /****** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&\r
- (stoppack == (j2k->cstr_info->num - 1))) */\r
- if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&\r
- (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&\r
- (stoppack == last_tp_pack))\r
- /* add the EOC len */\r
- prot_len += 2;\r
-\r
- /* let's add the EPBs */\r
- Psot += jpwl_epbs_add(\r
- j2k, /* J2K handle */\r
- jwmarker, /* pointer to JPWL markers list */\r
- &jwmarker_num, /* pointer to the number of current markers */\r
- OPJ_FALSE, /* latest */\r
- OPJ_TRUE, /* packed */\r
- OPJ_FALSE, /* inside MH */\r
- &epb_index, /* pointer to EPB index */\r
- pprot, /* protection type */\r
- /****** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001, */ /* position */\r
- (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */\r
- tileno, /* number of tile */\r
- 0, /* length of pre-data */\r
- prot_len /*4000*/ /* length of post-data */\r
- );\r
- }\r
-\r
- startpack = packno;\r
- pprot = j2k->cp->pprot[packspec++];\r
- }\r
-\r
- /*printf("Tile %02d, pack %02d ==> %d\n", tileno, packno, pprot);*/\r
- \r
- }\r
-\r
- /* we are at the end: print the remaining spec */\r
- stoppack = packno - 1;\r
- if (pprot >= 0) {\r
-\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- /**** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */\r
- "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",\r
- /**** tileno, */\r
- tileno, tpno,\r
- startpack,\r
- stoppack,\r
- /***** j2k->image_info->tile[tileno].packet[startpack].start_pos,\r
- j2k->image_info->tile[tileno].packet[stoppack].end_pos, */\r
- j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,\r
- j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,\r
- pprot);\r
-\r
- /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -\r
- j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */\r
- prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -\r
- j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;\r
-\r
- /*\r
- particular case: if this is the last header and the last packet,\r
- then it is better to protect even the EOC marker\r
- */\r
- /***** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&\r
- (stoppack == (j2k->cstr_info->num - 1))) */\r
- if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&\r
- (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&\r
- (stoppack == last_tp_pack))\r
- /* add the EOC len */\r
- prot_len += 2;\r
-\r
- /* let's add the EPBs */\r
- Psot += jpwl_epbs_add(\r
- j2k, /* J2K handle */\r
- jwmarker, /* pointer to JPWL markers list */\r
- &jwmarker_num, /* pointer to the number of current markers */\r
- OPJ_TRUE, /* latest */\r
- OPJ_TRUE, /* packed */\r
- OPJ_FALSE, /* inside MH */\r
- &epb_index, /* pointer to EPB index */\r
- pprot, /* protection type */\r
- /***** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001,*/ /* position */\r
- (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */\r
- tileno, /* number of tile */\r
- 0, /* length of pre-data */\r
- prot_len /*4000*/ /* length of post-data */\r
- );\r
- }\r
-\r
- /* we can now check if the TPH EPB was really the last one */\r
- if (tph_epb && (epb_index == 1)) {\r
- /* set the TPH EPB to be the last one in current header */\r
- tph_epb->Depb |= (unsigned char) ((OPJ_TRUE & 0x0001) << 6);\r
- tph_epb = NULL;\r
- }\r
-\r
- /* write back Psot */\r
- cio_seek(cio, Psotp);\r
- cio_write(cio, Psot, 4);\r
- \r
- }\r
-\r
- };\r
-\r
- /* reset the position */\r
- cio_seek(cio, ciopos);\r
-\r
-}\r
-\r
-void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {\r
-\r
- int mm;\r
- unsigned long int old_size = j2k->cstr_info->codestream_size;\r
- unsigned long int new_size = old_size;\r
- int /*ciopos = cio_tell(cio),*/ soc_pos = j2k->cstr_info->main_head_start;\r
- unsigned char *jpwl_buf, *orig_buf;\r
- unsigned long int orig_pos;\r
- double epbcoding_time = 0.0, esdcoding_time = 0.0;\r
- (void)image;\r
-\r
- /* Order JPWL markers according to their wishlist position */\r
- qsort((void *) jwmarker, (size_t) jwmarker_num, sizeof (jpwl_marker_t), jpwl_markcomp);\r
-\r
- /* compute markers total size */ \r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
- /*printf("%x, %d, %.10f, %d long\n", jwmarker[mm].id, jwmarker[mm].pos,\r
- jwmarker[mm].dpos, jwmarker[mm].len);*/\r
- new_size += jwmarker[mm].len + 2;\r
- }\r
-\r
- /* allocate a new buffer of proper size */\r
- if (!(jpwl_buf = (unsigned char *) opj_malloc((size_t) (new_size + soc_pos) * sizeof(unsigned char)))) {\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for JPWL codestream buffer\n");\r
- exit(1);\r
- };\r
-\r
- /* copy the jp2 part, if any */\r
- orig_buf = jpwl_buf;\r
- memcpy(jpwl_buf, cio->buffer, soc_pos);\r
- jpwl_buf += soc_pos;\r
-\r
- /* cycle through markers */\r
- orig_pos = soc_pos + 0; /* start from the beginning */\r
- cio_seek(cio, soc_pos + 0); /* rewind the original */\r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
-\r
- /*\r
- need to copy a piece of the original codestream\r
- if there is such\r
- */\r
- memcpy(jpwl_buf, cio_getbp(cio), jwmarker[mm].pos - orig_pos);\r
- jpwl_buf += jwmarker[mm].pos - orig_pos;\r
- orig_pos = jwmarker[mm].pos;\r
- cio_seek(cio, orig_pos);\r
-\r
- /*\r
- then write down the marker\r
- */\r
- switch (jwmarker[mm].id) {\r
-\r
- case J2K_MS_EPB:\r
- jpwl_epb_write(j2k, jwmarker[mm].m.epbmark, jpwl_buf);\r
- break;\r
-\r
- case J2K_MS_EPC:\r
- jpwl_epc_write(j2k, jwmarker[mm].m.epcmark, jpwl_buf);\r
- break;\r
-\r
- case J2K_MS_ESD:\r
- jpwl_esd_write(j2k, jwmarker[mm].m.esdmark, jpwl_buf);\r
- break;\r
-\r
- case J2K_MS_RED:\r
- memset(jpwl_buf, 0, jwmarker[mm].len + 2); /* placeholder */\r
- break;\r
-\r
- default:\r
- break;\r
- };\r
-\r
- /* we update the markers struct */\r
- if (j2k->cstr_info)\r
- j2k->cstr_info->marker[j2k->cstr_info->marknum - 1].pos = (jpwl_buf - orig_buf);\r
- \r
- /* we set the marker dpos to the new position in the JPWL codestream */\r
- jwmarker[mm].dpos = (double) (jpwl_buf - orig_buf);\r
-\r
- /* advance JPWL buffer position */\r
- jpwl_buf += jwmarker[mm].len + 2;\r
-\r
- }\r
-\r
- /* finish remaining original codestream */\r
- memcpy(jpwl_buf, cio_getbp(cio), old_size - (orig_pos - soc_pos));\r
- jpwl_buf += old_size - (orig_pos - soc_pos);\r
- cio_seek(cio, soc_pos + old_size);\r
- \r
- /*\r
- update info file based on added markers\r
- */\r
- if (!jpwl_update_info(j2k, jwmarker, jwmarker_num))\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not update OPJ cstr_info structure\n");\r
-\r
- /* now we need to repass some markers and fill their data fields */\r
- \r
- /* first of all, DL and Pcrc in EPCs */ \r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
-\r
- /* find the EPCs */\r
- if (jwmarker[mm].id == J2K_MS_EPC) {\r
-\r
- int epc_pos = (int) jwmarker[mm].dpos, pp;\r
- unsigned short int mycrc = 0x0000;\r
-\r
- /* fix and fill the DL field */\r
- jwmarker[mm].m.epcmark->DL = new_size;\r
- orig_buf[epc_pos + 6] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 24);\r
- orig_buf[epc_pos + 7] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 16);\r
- orig_buf[epc_pos + 8] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 8);\r
- orig_buf[epc_pos + 9] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 0);\r
-\r
- /* compute the CRC field (excluding itself) */\r
- for (pp = 0; pp < 4; pp++)\r
- jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);\r
- for (pp = 6; pp < (jwmarker[mm].len + 2); pp++)\r
- jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);\r
-\r
- /* fix and fill the CRC */\r
- jwmarker[mm].m.epcmark->Pcrc = mycrc;\r
- orig_buf[epc_pos + 4] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 8);\r
- orig_buf[epc_pos + 5] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 0);\r
-\r
- }\r
- }\r
-\r
- /* then, sensitivity data in ESDs */ \r
- esdcoding_time = opj_clock();\r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
-\r
- /* find the ESDs */\r
- if (jwmarker[mm].id == J2K_MS_ESD) {\r
-\r
- /* remember that they are now in a new position (dpos) */\r
- int esd_pos = (int) jwmarker[mm].dpos;\r
-\r
- jpwl_esd_fill(j2k, jwmarker[mm].m.esdmark, &orig_buf[esd_pos]);\r
- \r
- }\r
-\r
- }\r
- esdcoding_time = opj_clock() - esdcoding_time;\r
- if (j2k->cp->esd_on)\r
- opj_event_msg(j2k->cinfo, EVT_INFO, "ESDs sensitivities computed in %f s\n", esdcoding_time);\r
-\r
- /* finally, RS or CRC parity in EPBs */ \r
- epbcoding_time = opj_clock();\r
- for (mm = 0; mm < jwmarker_num; mm++) {\r
-\r
- /* find the EPBs */\r
- if (jwmarker[mm].id == J2K_MS_EPB) {\r
-\r
- /* remember that they are now in a new position (dpos) */\r
- int nn, accum_len;\r
-\r
- /* let's see how many EPBs are following this one, included itself */\r
- /* for this to work, we suppose that the markers are correctly ordered */\r
- /* and, overall, that they are in packed mode inside headers */\r
- accum_len = 0;\r
- for (nn = mm; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&\r
- (jwmarker[nn].pos == jwmarker[mm].pos); nn++)\r
- accum_len += jwmarker[nn].m.epbmark->Lepb + 2;\r
-\r
- /* fill the current (first) EPB with post-data starting from the computed position */\r
- jpwl_epb_fill(j2k, jwmarker[mm].m.epbmark, &orig_buf[(int) jwmarker[mm].dpos],\r
- &orig_buf[(int) jwmarker[mm].dpos + accum_len]);\r
- \r
- /* fill the remaining EPBs in the header with post-data starting from the last position */\r
- for (nn = mm + 1; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&\r
- (jwmarker[nn].pos == jwmarker[mm].pos); nn++)\r
- jpwl_epb_fill(j2k, jwmarker[nn].m.epbmark, &orig_buf[(int) jwmarker[nn].dpos], NULL);\r
-\r
- /* skip all the processed EPBs */\r
- mm = nn - 1;\r
- }\r
-\r
- }\r
- epbcoding_time = opj_clock() - epbcoding_time;\r
- if (j2k->cp->epb_on)\r
- opj_event_msg(j2k->cinfo, EVT_INFO, "EPBs redundancy computed in %f s\n", epbcoding_time);\r
-\r
- /* free original cio buffer and set it to the JPWL one */\r
- opj_free(cio->buffer);\r
- cio->cinfo = cio->cinfo; /* no change */\r
- cio->openmode = cio->openmode; /* no change */\r
- cio->buffer = orig_buf;\r
- cio->length = new_size + soc_pos;\r
- cio->start = cio->buffer;\r
- cio->end = cio->buffer + cio->length;\r
- cio->bp = cio->buffer;\r
- cio_seek(cio, soc_pos + new_size);\r
-\r
-}\r
-\r
-\r
-void j2k_read_epc(opj_j2k_t *j2k) {\r
- unsigned long int DL, Lepcp, Pcrcp, l;\r
- unsigned short int Lepc, Pcrc = 0x0000;\r
- unsigned char Pepc; \r
- opj_cio_t *cio = j2k->cio;\r
- const char *ans1;\r
-\r
- /* Simply read the EPC parameters */\r
- Lepcp = cio_tell(cio);\r
- Lepc = cio_read(cio, 2);\r
- Pcrcp = cio_tell(cio);\r
- cio_skip(cio, 2); /* Pcrc */\r
- DL = cio_read(cio, 4);\r
- Pepc = cio_read(cio, 1);\r
-\r
- /* compute Pcrc */\r
- cio_seek(cio, Lepcp - 2);\r
-\r
- /* Marker */\r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
-\r
- /* Length */\r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
-\r
- /* skip Pcrc */\r
- cio_skip(cio, 2);\r
-\r
- /* read all remaining */\r
- for (l = 4; l < Lepc; l++)\r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
-\r
- /* check Pcrc with the result */\r
- cio_seek(cio, Pcrcp);\r
- ans1 = (Pcrc == (unsigned short int) cio_read(cio, 2)) ? "crc-ok" : "crc-ko";\r
-\r
- /* now we write them to screen */\r
- opj_event_msg(j2k->cinfo, EVT_INFO, \r
- "EPC(%u,%d): %s, DL=%d%s %s %s\n",\r
- Lepcp - 2,\r
- Lepc,\r
- ans1,\r
- DL, /* data length this EPC is referring to */\r
- (Pepc & 0x10) ? ", esd" : "", /* ESD is present */\r
- (Pepc & 0x20) ? ", red" : "", /* RED is present */\r
- (Pepc & 0x40) ? ", epb" : ""); /* EPB is present */\r
-\r
- cio_seek(cio, Lepcp + Lepc); \r
-}\r
-\r
-void j2k_write_epc(opj_j2k_t *j2k) {\r
-\r
- unsigned long int DL, Lepcp, Pcrcp, l;\r
- unsigned short int Lepc, Pcrc;\r
- unsigned char Pepc; \r
-\r
- opj_cio_t *cio = j2k->cio;\r
-\r
- cio_write(cio, J2K_MS_EPC, 2); /* EPC */\r
- Lepcp = cio_tell(cio);\r
- cio_skip(cio, 2);\r
-\r
- /* CRC-16 word of the EPC */\r
- Pcrc = 0x0000; /* initialize */\r
- Pcrcp = cio_tell(cio);\r
- cio_write(cio, Pcrc, 2); /* Pcrc placeholder*/\r
-\r
- /* data length of the EPC protection domain */\r
- DL = 0x00000000; /* we leave this set to 0, as if the information is not available */\r
- cio_write(cio, DL, 4); /* DL */\r
-\r
- /* jpwl capabilities */\r
- Pepc = 0x00;\r
- cio_write(cio, Pepc, 1); /* Pepc */\r
-\r
- /* ID section */\r
- /* no ID's, as of now */\r
-\r
- Lepc = (unsigned short) (cio_tell(cio) - Lepcp);\r
- cio_seek(cio, Lepcp);\r
- cio_write(cio, Lepc, 2); /* Lepc */\r
-\r
- /* compute Pcrc */\r
- cio_seek(cio, Lepcp - 2);\r
-\r
- /* Marker */\r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
-\r
- /* Length */\r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
-\r
- /* skip Pcrc */\r
- cio_skip(cio, 2);\r
-\r
- /* read all remaining */\r
- for (l = 4; l < Lepc; l++)\r
- jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1)); \r
-\r
- /* fill Pcrc with the result */\r
- cio_seek(cio, Pcrcp);\r
- cio_write(cio, Pcrc, 2);\r
-\r
- cio_seek(cio, Lepcp + Lepc);\r
-\r
- /* marker struct update */\r
- j2k_add_marker(j2k->cstr_info, J2K_MS_EPC, Lepcp - 2, Lepc + 2);\r
-\r
-}\r
-\r
-void j2k_read_epb(opj_j2k_t *j2k) {\r
- unsigned long int LDPepb, Pepb;\r
- unsigned short int Lepb;\r
- unsigned char Depb;\r
- char str1[25] = "";\r
- opj_bool status;\r
- static opj_bool first_in_tph = OPJ_TRUE;\r
- int type, pre_len, post_len;\r
- static unsigned char *redund = NULL;\r
- \r
- opj_cio_t *cio = j2k->cio;\r
-\r
- /* B/W = 45, RGB = 51 */\r
- /* SIZ SIZ_FIELDS SIZ_COMPS FOLLOWING_MARKER */\r
- int skipnum = 2 + 38 + 3 * j2k->cp->exp_comps + 2;\r
-\r
- if (j2k->cp->correct) {\r
-\r
- /* go back to EPB marker value */\r
- cio_seek(cio, cio_tell(cio) - 2);\r
-\r
- /* we need to understand where we are */\r
- if (j2k->state == J2K_STATE_MH) {\r
- /* we are in MH */\r
- type = 0; /* MH */\r
- pre_len = skipnum; /* SOC+SIZ */\r
- post_len = -1; /* auto */\r
-\r
- } else if ((j2k->state == J2K_STATE_TPH) && first_in_tph) {\r
- /* we are in TPH */\r
- type = 1; /* TPH */\r
- pre_len = 12; /* SOC+SIZ */\r
- first_in_tph = OPJ_FALSE;\r
- post_len = -1; /* auto */\r
-\r
- } else {\r
- /* we are elsewhere */\r
- type = 2; /* other */\r
- pre_len = 0; /* nada */\r
- post_len = -1; /* auto */\r
-\r
- }\r
-\r
- /* call EPB corrector */\r
- /*printf("before %x, ", redund);*/\r
- status = jpwl_epb_correct(j2k, /* J2K decompressor handle */\r
- cio->bp, /* pointer to EPB in codestream buffer */\r
- type, /* EPB type: MH */\r
- pre_len, /* length of pre-data */\r
- post_len, /* length of post-data: -1 means auto */\r
- NULL, /* do everything auto */\r
- &redund\r
- );\r
- /*printf("after %x\n", redund);*/\r
-\r
- /* Read the (possibly corrected) EPB parameters */\r
- cio_skip(cio, 2);\r
- Lepb = cio_read(cio, 2);\r
- Depb = cio_read(cio, 1);\r
- LDPepb = cio_read(cio, 4);\r
- Pepb = cio_read(cio, 4);\r
-\r
- if (!status) {\r
-\r
- opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL correction could not be performed\n");\r
-\r
- /* advance to EPB endpoint */\r
- cio_skip(cio, Lepb + 2); \r
-\r
- return;\r
- }\r
-\r
- /* last in current header? */\r
- if (Depb & 0x40) {\r
- redund = NULL; /* reset the pointer to L4 buffer */\r
- first_in_tph = OPJ_TRUE;\r
- }\r
-\r
- /* advance to EPB endpoint */\r
- cio_skip(cio, Lepb - 11); \r
-\r
- } else {\r
-\r
- /* Simply read the EPB parameters */\r
- Lepb = cio_read(cio, 2);\r
- Depb = cio_read(cio, 1);\r
- LDPepb = cio_read(cio, 4);\r
- Pepb = cio_read(cio, 4);\r
-\r
- /* What does Pepb tells us about the protection method? */\r
- if (((Pepb & 0xF0000000) >> 28) == 0)\r
- sprintf(str1, "pred"); /* predefined */\r
- else if (((Pepb & 0xF0000000) >> 28) == 1)\r
- sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */\r
- else if (((Pepb & 0xF0000000) >> 28) == 2)\r
- sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */\r
- else if (Pepb == 0xFFFFFFFF)\r
- sprintf(str1, "nometh"); /* RS mode */\r
- else\r
- sprintf(str1, "unknown"); /* unknown */\r
-\r
- /* Now we write them to screen */\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "EPB(%d): (%sl, %sp, %u), %lu, %s\n",\r
- cio_tell(cio) - 13,\r
- (Depb & 0x40) ? "" : "n", /* latest EPB or not? */\r
- (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */\r
- (Depb & 0x3F), /* EPB index value */\r
- LDPepb, /*length of the data protected by the EPB */\r
- str1); /* protection method */\r
-\r
- cio_skip(cio, Lepb - 11); \r
- }\r
-}\r
-\r
-void j2k_write_epb(opj_j2k_t *j2k) {\r
- unsigned long int LDPepb, Pepb, Lepbp;\r
- unsigned short int Lepb;\r
- unsigned char Depb;\r
-\r
- opj_cio_t *cio = j2k->cio;\r
-\r
- cio_write(cio, J2K_MS_EPB, 2); /* EPB */\r
- Lepbp = cio_tell(cio);\r
- cio_skip(cio, 2);\r
-\r
- /* EPB style */\r
- Depb = 0x00; /* test */\r
- cio_write(cio, Depb, 1); /* Depb */\r
-\r
- /* length of the data to be protected by this EPB */\r
- LDPepb = 0x00000000; /* test */\r
- cio_write(cio, LDPepb, 4); /* LDPepb */\r
-\r
- /* next error correction tool */\r
- Pepb = 0x00000000; /* test */\r
- cio_write(cio, Pepb, 4); /* Pepb */\r
-\r
- /* EPB data */\r
- /* no data, as of now */\r
-\r
- Lepb = (unsigned short) (cio_tell(cio) - Lepbp);\r
- cio_seek(cio, Lepbp);\r
- cio_write(cio, Lepb, 2); /* Lepb */\r
-\r
- cio_seek(cio, Lepbp + Lepb);\r
-\r
- /* marker struct update */\r
- j2k_add_marker(j2k->cstr_info, J2K_MS_EPB, Lepbp - 2, Lepb + 2);\r
-}\r
-\r
-void j2k_read_esd(opj_j2k_t *j2k) {\r
- unsigned short int Lesd, Cesd;\r
- unsigned char Pesd;\r
-\r
- int cesdsize = (j2k->image->numcomps >= 257) ? 2 : 1;\r
-\r
- char str1[4][4] = {"p", "br", "pr", "res"};\r
- char str2[8][8] = {"res", "mse", "mse-r", "psnr", "psnr-i", "maxerr", "tse", "res"};\r
- \r
- opj_cio_t *cio = j2k->cio;\r
-\r
- /* Simply read the ESD parameters */\r
- Lesd = cio_read(cio, 2);\r
- Cesd = cio_read(cio, cesdsize);\r
- Pesd = cio_read(cio, 1);\r
-\r
- /* Now we write them to screen */\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "ESD(%d): c%d, %s, %s, %s, %s, %s\n",\r
- cio_tell(cio) - (5 + cesdsize),\r
- Cesd, /* component number for this ESD */\r
- str1[(Pesd & (unsigned char) 0xC0) >> 6], /* addressing mode */\r
- str2[(Pesd & (unsigned char) 0x38) >> 3], /* sensitivity type */\r
- ((Pesd & (unsigned char) 0x04) >> 2) ? "2Bs" : "1Bs",\r
- ((Pesd & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba",\r
- (Pesd & (unsigned char) 0x01) ? "avgc" : "");\r
-\r
- cio_skip(cio, Lesd - (3 + cesdsize)); \r
-}\r
-\r
-void j2k_read_red(opj_j2k_t *j2k) {\r
- unsigned short int Lred;\r
- unsigned char Pred;\r
- char str1[4][4] = {"p", "br", "pr", "res"};\r
- \r
- opj_cio_t *cio = j2k->cio;\r
-\r
- /* Simply read the RED parameters */\r
- Lred = cio_read(cio, 2);\r
- Pred = cio_read(cio, 1);\r
-\r
- /* Now we write them to screen */\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "RED(%d): %s, %dc, %s, %s\n",\r
- cio_tell(cio) - 5,\r
- str1[(Pred & (unsigned char) 0xC0) >> 6], /* addressing mode */\r
- (Pred & (unsigned char) 0x38) >> 3, /* corruption level */\r
- ((Pred & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba", /* address range */\r
- (Pred & (unsigned char) 0x01) ? "errs" : "free"); /* error free? */\r
-\r
- cio_skip(cio, Lred - 3); \r
-}\r
-\r
-opj_bool jpwl_check_tile(opj_j2k_t *j2k, opj_tcd_t *tcd, int tileno) {\r
-\r
-#ifdef oerhgierhgvhreit4u\r
- /*\r
- we navigate through the tile and find possible invalid parameters:\r
- this saves a lot of crashes!!!!!\r
- */\r
- int compno, resno, precno, /*layno,*/ bandno, blockno;\r
- int numprecincts, numblocks;\r
-\r
- /* this is the selected tile */\r
- opj_tcd_tile_t *tile = &(tcd->tcd_image->tiles[tileno]);\r
-\r
- /* will keep the component */\r
- opj_tcd_tilecomp_t *comp = NULL;\r
-\r
- /* will keep the resolution */\r
- opj_tcd_resolution_t *res;\r
-\r
- /* will keep the subband */\r
- opj_tcd_band_t *band; \r
-\r
- /* will keep the precinct */\r
- opj_tcd_precinct_t *prec; \r
-\r
- /* will keep the codeblock */\r
- opj_tcd_cblk_t *block;\r
-\r
- /* check all tile components */\r
- for (compno = 0; compno < tile->numcomps; compno++) {\r
- comp = &(tile->comps[compno]);\r
-\r
- /* check all component resolutions */\r
- for (resno = 0; resno < comp->numresolutions; resno++) {\r
- res = &(comp->resolutions[resno]);\r
- numprecincts = res->pw * res->ph;\r
-\r
- /* check all the subbands */\r
- for (bandno = 0; bandno < res->numbands; bandno++) {\r
- band = &(res->bands[bandno]);\r
-\r
- /* check all the precincts */\r
- for (precno = 0; precno < numprecincts; precno++) {\r
- prec = &(band->precincts[precno]);\r
- numblocks = prec->ch * prec->cw;\r
-\r
- /* check all the codeblocks */\r
- for (blockno = 0; blockno < numblocks; blockno++) {\r
- block = &(prec->cblks[blockno]);\r
-\r
- /* x-origin is invalid */\r
- if ((block->x0 < prec->x0) || (block->x0 > prec->x1)) {\r
- opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,\r
- "JPWL: wrong x-cord of block origin %d => x-prec is (%d, %d)\n",\r
- block->x0, prec->x0, prec->x1);\r
- if (!JPWL_ASSUME || JPWL_ASSUME)\r
- return OPJ_FALSE;\r
- };\r
- }\r
- } \r
- }\r
- }\r
- }\r
-\r
-#else\r
- (void)j2k;\r
- (void)tcd;\r
- (void)tileno;\r
-#endif\r
-\r
- return OPJ_TRUE;\r
-}\r
-\r
-/*@}*/\r
-\r
-#endif /* USE_JPWL */\r
-\r
-\r
-#ifdef USE_JPSEC\r
-\r
-/** @defgroup JPSEC JPSEC - JPEG-2000 Part 8 (JPSEC) codestream manager */\r
-/*@{*/\r
-\r
-\r
-/** @name Local static functions */\r
-/*@{*/\r
-\r
-void j2k_read_sec(opj_j2k_t *j2k) {\r
- unsigned short int Lsec;\r
- \r
- opj_cio_t *cio = j2k->cio;\r
-\r
- /* Simply read the SEC length */\r
- Lsec = cio_read(cio, 2);\r
-\r
- /* Now we write them to screen */\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "SEC(%d)\n",\r
- cio_tell(cio) - 2\r
- );\r
-\r
- cio_skip(cio, Lsec - 2); \r
-}\r
-\r
-void j2k_write_sec(opj_j2k_t *j2k) {\r
- unsigned short int Lsec = 24;\r
- int i;\r
-\r
- opj_cio_t *cio = j2k->cio;\r
-\r
- cio_write(cio, J2K_MS_SEC, 2); /* SEC */\r
- cio_write(cio, Lsec, 2);\r
-\r
- /* write dummy data */\r
- for (i = 0; i < Lsec - 2; i++)\r
- cio_write(cio, 0, 1);\r
-}\r
-\r
-void j2k_read_insec(opj_j2k_t *j2k) {\r
- unsigned short int Linsec;\r
- \r
- opj_cio_t *cio = j2k->cio;\r
-\r
- /* Simply read the INSEC length */\r
- Linsec = cio_read(cio, 2);\r
-\r
- /* Now we write them to screen */\r
- opj_event_msg(j2k->cinfo, EVT_INFO,\r
- "INSEC(%d)\n",\r
- cio_tell(cio) - 2\r
- );\r
-\r
- cio_skip(cio, Linsec - 2); \r
-}\r
-\r
-\r
-/*@}*/\r
-\r
-/*@}*/\r
-\r
-#endif /* USE_JPSEC */\r
-\r
+/*
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opj_includes.h"
+
+#ifdef USE_JPWL
+
+/** @defgroup JPWL JPWL - JPEG-2000 Part11 (JPWL) codestream manager */
+/*@{*/
+
+/** @name Local static variables */
+/*@{*/
+
+/** number of JPWL prepared markers */
+static int jwmarker_num;
+/** properties of JPWL markers to insert */
+static jpwl_marker_t jwmarker[JPWL_MAX_NO_MARKERS];
+
+/*@}*/
+
+/*@}*/
+
+/** @name Local static functions */
+/*@{*/
+
+/** create an EPC marker segment
+@param j2k J2K compressor handle
+@param esd_on true if ESD is activated
+@param red_on true if RED is activated
+@param epb_on true if EPB is activated
+@param info_on true if informative techniques are activated
+@return returns the freshly created EPC
+*/
+jpwl_epc_ms_t *jpwl_epc_create(opj_j2k_t *j2k, opj_bool esd_on, opj_bool red_on, opj_bool epb_on, opj_bool info_on);
+
+/*@}*/
+
+/** create an EPC marker segment
+@param j2k J2K compressor handle
+@param comps considered component (-1=average, 0/1/2/...=component no.)
+@param addrm addressing mode (0=packet, 1=byte range, 2=packet range, 3=reserved)
+@param ad_size size of addresses (2/4 bytes)
+@param senst sensitivity type
+@param se_size sensitivity values size (1/2 bytes)
+@param tileno tile where this ESD lies (-1 means MH)
+@param svalnum number of sensitivity values (if 0, they will be automatically filled)
+@param sensval pointer to an array of sensitivity values (if NULL, they will be automatically filled)
+@return returns the freshly created ESD
+*/
+jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comps,
+ unsigned char addrm, unsigned char ad_size,
+ unsigned char senst, int se_size, int tileno,
+ unsigned long int svalnum, void *sensval);
+
+/** this function is used to compare two JPWL markers based on
+their relevant wishlist position
+@param arg1 pointer to first marker
+@param arg2 pointer to second marker
+@return 1 if arg1>arg2, 0 if arg1=arg2, -1 if arg1<arg2
+*/
+int jpwl_markcomp(const void *arg1, const void *arg2);
+
+/** write an EPB MS to a buffer
+@param j2k J2K compressor handle
+@param epbmark pointer to the EPB MS
+@param buf pointer to the memory buffer
+*/
+void jpwl_epb_write(opj_j2k_t *j2k, jpwl_epb_ms_t *epbmark, unsigned char *buf);
+
+/** write an EPC MS to a buffer
+@param j2k J2K compressor handle
+@param epcmark pointer to the EPC MS
+@param buf pointer to the memory buffer
+*/
+void jpwl_epc_write(opj_j2k_t *j2k, jpwl_epc_ms_t *epcmark, unsigned char *buf);
+
+/** write an ESD MS to a buffer
+@param j2k J2K compressor handle
+@param esdmark pointer to the ESD MS
+@param buf pointer to the memory buffer
+*/
+void jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esdmark, unsigned char *buf);
+
+/*-----------------------------------------------------------------*/
+
+void jpwl_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
+
+ int mm;
+
+ /* let's reset some settings */
+
+ /* clear the existing markers */
+ for (mm = 0; mm < jwmarker_num; mm++) {
+
+ switch (jwmarker[mm].id) {
+
+ case J2K_MS_EPB:
+ opj_free(jwmarker[mm].m.epbmark);
+ break;
+
+ case J2K_MS_EPC:
+ opj_free(jwmarker[mm].m.epcmark);
+ break;
+
+ case J2K_MS_ESD:
+ opj_free(jwmarker[mm].m.esdmark);
+ break;
+
+ case J2K_MS_RED:
+ opj_free(jwmarker[mm].m.redmark);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* clear the marker structure array */
+ memset(jwmarker, 0, sizeof(jpwl_marker_t) * JPWL_MAX_NO_MARKERS);
+
+ /* no more markers in the list */
+ jwmarker_num = 0;
+
+ /* let's begin creating a marker list, according to user wishes */
+ jpwl_prepare_marks(j2k, cio, image);
+
+ /* now we dump the JPWL markers on the codestream */
+ jpwl_dump_marks(j2k, cio, image);
+
+ /* do not know exactly what is this for,
+ but it gets called during index creation */
+ j2k->pos_correction = 0;
+
+}
+
+void j2k_add_marker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
+
+ if (!cstr_info)
+ return;
+
+ /* expand the list? */
+ if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
+ cstr_info->maxmarknum += 100;
+ cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum * sizeof(opj_marker_info_t));
+ }
+
+ /* add the marker */
+ cstr_info->marker[cstr_info->marknum].type = type;
+ cstr_info->marker[cstr_info->marknum].pos = pos;
+ cstr_info->marker[cstr_info->marknum].len = len;
+ cstr_info->marknum++;
+
+}
+
+void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
+
+ unsigned short int socsiz_len = 0;
+ int ciopos = cio_tell(cio), soc_pos = j2k->cstr_info->main_head_start;
+ unsigned char *socp = NULL;
+
+ int tileno, acc_tpno, tpno, tilespec, hprot, sens, pprot, packspec, lastileno, packno;
+
+ jpwl_epb_ms_t *epb_mark;
+ jpwl_epc_ms_t *epc_mark;
+ jpwl_esd_ms_t *esd_mark;
+ (void)image;
+
+ /* find (SOC + SIZ) length */
+ /* I assume SIZ is always the first marker after SOC */
+ cio_seek(cio, soc_pos + 4);
+ socsiz_len = (unsigned short int) cio_read(cio, 2) + 4; /* add the 2 marks length itself */
+ cio_seek(cio, soc_pos + 0);
+ socp = cio_getbp(cio); /* pointer to SOC */
+
+ /*
+ EPC MS for Main Header: if we are here it's required
+ */
+ /* create the EPC */
+ if ((epc_mark = jpwl_epc_create(
+ j2k,
+ j2k->cp->esd_on, /* is ESD present? */
+ j2k->cp->red_on, /* is RED present? */
+ j2k->cp->epb_on, /* is EPB present? */
+ OPJ_FALSE /* are informative techniques present? */
+ ))) {
+
+ /* Add this marker to the 'insertanda' list */
+ if (epc_mark) {
+ jwmarker[jwmarker_num].id = J2K_MS_EPC; /* its type */
+ jwmarker[jwmarker_num].m.epcmark = epc_mark; /* the EPC */
+ jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
+ jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.1; /* not so first */
+ jwmarker[jwmarker_num].len = epc_mark->Lepc; /* its length */
+ jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].parms_ready = OPJ_FALSE; /* not ready */
+ jwmarker[jwmarker_num].data_ready = OPJ_TRUE; /* ready */
+ jwmarker_num++;
+ };
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "MH EPC : setting %s%s%s\n",
+ j2k->cp->esd_on ? "ESD, " : "",
+ j2k->cp->red_on ? "RED, " : "",
+ j2k->cp->epb_on ? "EPB, " : ""
+ );
+
+ } else {
+ /* ooops, problems */
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPC\n");
+ };
+
+ /*
+ ESD MS for Main Header
+ */
+ /* first of all, must MH have an ESD MS? */
+ if (j2k->cp->esd_on && (j2k->cp->sens_MH >= 0)) {
+
+ /* Create the ESD */
+ if ((esd_mark = jpwl_esd_create(
+ j2k, /* this encoder handle */
+ -1, /* we are averaging over all components */
+ (unsigned char) j2k->cp->sens_range, /* range method */
+ (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing */
+ (unsigned char) j2k->cp->sens_MH, /* sensitivity method */
+ j2k->cp->sens_size, /* sensitivity size */
+ -1, /* this ESD is in main header */
+ 0 /*j2k->cstr_info->num*/, /* number of packets in codestream */
+ NULL /*sensval*/ /* pointer to sensitivity data of packets */
+ ))) {
+
+ /* Add this marker to the 'insertanda' list */
+ if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
+ jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
+ jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
+ jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* we choose to place it after SIZ */
+ jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
+ jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
+ jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* not ready, yet */
+ jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* not ready */
+ jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */
+ jwmarker_num++;
+ }
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "MH ESDs: method %d\n",
+ j2k->cp->sens_MH
+ );
+
+ } else {
+ /* ooops, problems */
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH ESD\n");
+ };
+
+ }
+
+ /*
+ ESD MSs for Tile Part Headers
+ */
+ /* cycle through tiles */
+ sens = -1; /* default spec: no ESD */
+ tilespec = 0; /* first tile spec */
+ acc_tpno = 0;
+ for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "Tile %d has %d tile part(s)\n",
+ tileno, j2k->cstr_info->tile[tileno].num_tps
+ );
+
+ /* for every tile part in the tile */
+ for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
+
+ int sot_len, Psot, Psotp, mm;
+ unsigned long sot_pos, post_sod_pos;
+
+ unsigned long int left_THmarks_len;
+
+ /******* sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
+ sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
+ cio_seek(cio, sot_pos + 2);
+ sot_len = cio_read(cio, 2); /* SOT Len */
+ cio_skip(cio, 2);
+ Psotp = cio_tell(cio);
+ Psot = cio_read(cio, 4); /* tile length */
+
+ /******* post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
+ post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
+ left_THmarks_len = post_sod_pos - sot_pos;
+
+ /* add all the lengths of the markers which are len-ready and stay within SOT and SOD */
+ for (mm = 0; mm < jwmarker_num; mm++) {
+ if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
+ if (jwmarker[mm].len_ready)
+ left_THmarks_len += jwmarker[mm].len + 2;
+ else {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
+ jwmarker[mm].id, jwmarker[mm].dpos);
+ exit(1);
+ }
+ }
+ }
+
+ /******* if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == tileno)) */
+ if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == acc_tpno))
+ /* we got a specification from this tile onwards */
+ sens = j2k->cp->sens_TPH[tilespec++];
+
+ /* must this TPH have an ESD MS? */
+ if (j2k->cp->esd_on && (sens >= 0)) {
+
+ /* Create the ESD */
+ if ((esd_mark = jpwl_esd_create(
+ j2k, /* this encoder handle */
+ -1, /* we are averaging over all components */
+ (unsigned char) j2k->cp->sens_range, /* range method */
+ (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing size */
+ (unsigned char) sens, /* sensitivity method */
+ j2k->cp->sens_size, /* sensitivity value size */
+ tileno, /* this ESD is in a tile */
+ 0, /* number of packets in codestream */
+ NULL /* pointer to sensitivity data of packets */
+ ))) {
+
+ /* Add this marker to the 'insertanda' list */
+ if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
+ jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
+ jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
+ /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
+ jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
+ jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
+ jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
+ jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready, yet */
+ jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* not ready */
+ jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* ready */
+ jwmarker_num++;
+ }
+
+ /* update Psot of the tile */
+ cio_seek(cio, Psotp);
+ cio_write(cio, Psot + esd_mark->Lesd + 2, 4);
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ /******* "TPH ESDs: tile %02d, method %d\n", */
+ "TPH ESDs: tile %02d, part %02d, method %d\n",
+ /******* tileno, */
+ tileno, tpno,
+ sens
+ );
+
+ } else {
+ /* ooops, problems */
+ /***** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d\n", tileno); */
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d,%d\n", tileno, tpno);
+ };
+
+ }
+
+ }
+
+ };
+
+ /*
+ EPB MS for Main Header
+ */
+ /* first of all, must MH have an EPB MS? */
+ if (j2k->cp->epb_on && (j2k->cp->hprot_MH > 0)) {
+
+ int mm;
+
+ /* position of SOT */
+ unsigned int sot_pos = j2k->cstr_info->main_head_end + 1;
+
+ /* how much space is there between end of SIZ and beginning of SOT? */
+ int left_MHmarks_len = sot_pos - socsiz_len;
+
+ /* add all the lengths of the markers which are len-ready and stay within SOC and SOT */
+ for (mm = 0; mm < jwmarker_num; mm++) {
+ if ( jwmarker[mm].pos < sot_pos) { /* jwmarker[mm].pos >=0 since ulong */
+ if (jwmarker[mm].len_ready)
+ left_MHmarks_len += jwmarker[mm].len + 2;
+ else {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up MH EPB\n",
+ jwmarker[mm].id, jwmarker[mm].dpos);
+ exit(1);
+ }
+ }
+ }
+
+ /* Create the EPB */
+ if ((epb_mark = jpwl_epb_create(
+ j2k, /* this encoder handle */
+ OPJ_TRUE, /* is it the latest? */
+ OPJ_TRUE, /* is it packed? not for now */
+ -1, /* we are in main header */
+ 0, /* its index is 0 (first) */
+ j2k->cp->hprot_MH, /* protection type parameters of data */
+ socsiz_len, /* pre-data: only SOC+SIZ */
+ left_MHmarks_len /* post-data: from SOC to SOT, and all JPWL markers within */
+ ))) {
+
+ /* Add this marker to the 'insertanda' list */
+ if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
+ jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
+ jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
+ jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
+ jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
+ jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
+ jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */
+ jwmarker_num++;
+ }
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "MH EPB : prot. %d\n",
+ j2k->cp->hprot_MH
+ );
+
+ } else {
+ /* ooops, problems */
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPB\n");
+ };
+ }
+
+ /*
+ EPB MSs for Tile Parts
+ */
+ /* cycle through TPHs */
+ hprot = j2k->cp->hprot_MH; /* default spec */
+ tilespec = 0; /* first tile spec */
+ lastileno = 0;
+ packspec = 0;
+ pprot = -1;
+ acc_tpno = 0;
+ for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "Tile %d has %d tile part(s)\n",
+ tileno, j2k->cstr_info->tile[tileno].num_tps
+ );
+
+ /* for every tile part in the tile */
+ for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
+
+ int sot_len, Psot, Psotp, mm, epb_index = 0, prot_len = 0;
+ unsigned long sot_pos, post_sod_pos;
+ unsigned long int left_THmarks_len/*, epbs_len = 0*/;
+ int startpack = 0, stoppack = j2k->cstr_info->packno;
+ int first_tp_pack, last_tp_pack;
+ jpwl_epb_ms_t *tph_epb = NULL;
+
+ /****** sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
+ sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
+ cio_seek(cio, sot_pos + 2);
+ sot_len = cio_read(cio, 2); /* SOT Len */
+ cio_skip(cio, 2);
+ Psotp = cio_tell(cio);
+ Psot = cio_read(cio, 4); /* tile length */
+
+ /* a-priori length of the data dwelling between SOT and SOD */
+ /****** post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
+ post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
+ left_THmarks_len = post_sod_pos - (sot_pos + sot_len + 2);
+
+ /* add all the lengths of the JPWL markers which are len-ready and stay within SOT and SOD */
+ for (mm = 0; mm < jwmarker_num; mm++) {
+ if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
+ if (jwmarker[mm].len_ready)
+ left_THmarks_len += jwmarker[mm].len + 2;
+ else {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
+ jwmarker[mm].id, jwmarker[mm].dpos);
+ exit(1);
+ }
+ }
+ }
+
+ /****** if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == tileno)) */
+ if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == acc_tpno))
+ /* we got a specification from this tile part onwards */
+ hprot = j2k->cp->hprot_TPH[tilespec++];
+
+ /* must this TPH have an EPB MS? */
+ if (j2k->cp->epb_on && (hprot > 0)) {
+
+ /* Create the EPB */
+ if ((epb_mark = jpwl_epb_create(
+ j2k, /* this encoder handle */
+ OPJ_FALSE, /* is it the latest? in TPH, no for now (if huge data size in TPH, we'd need more) */
+ OPJ_TRUE, /* is it packed? yes for now */
+ tileno, /* we are in TPH */
+ epb_index++, /* its index is 0 (first) */
+ hprot, /* protection type parameters of following data */
+ sot_len + 2, /* pre-data length: only SOT */
+ left_THmarks_len /* post-data length: from SOT end to SOD inclusive */
+ ))) {
+
+ /* Add this marker to the 'insertanda' list */
+ if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
+ jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
+ jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
+ /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
+ jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
+ jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
+ jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
+ jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* ready */
+ jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */
+ jwmarker_num++;
+ }
+
+ /* update Psot of the tile */
+ Psot += epb_mark->Lepb + 2;
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ /***** "TPH EPB : tile %02d, prot. %d\n", */
+ "TPH EPB : tile %02d, part %02d, prot. %d\n",
+ /***** tileno, */
+ tileno, tpno,
+ hprot
+ );
+
+ /* save this TPH EPB address */
+ tph_epb = epb_mark;
+
+ } else {
+ /* ooops, problems */
+ /****** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB #%d\n", tileno); */
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB in #%d,d\n", tileno, tpno);
+ };
+
+ }
+
+ startpack = 0;
+ /* EPB MSs for UEP packet data protection in Tile Parts */
+ /****** for (packno = 0; packno < j2k->cstr_info->num; packno++) { */
+ /*first_tp_pack = (tpno > 0) ? (first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno - 1].tp_numpacks) : 0;*/
+ first_tp_pack = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pack;
+ last_tp_pack = first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks - 1;
+ for (packno = 0; packno < j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks; packno++) {
+
+ /******** if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
+ (j2k->cp->pprot_tileno[packspec] == tileno) && (j2k->cp->pprot_packno[packspec] == packno)) { */
+ if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
+ (j2k->cp->pprot_tileno[packspec] == acc_tpno) && (j2k->cp->pprot_packno[packspec] == packno)) {
+
+ /* we got a specification from this tile and packet onwards */
+ /* print the previous spec */
+ if (packno > 0) {
+ stoppack = packno - 1;
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ /***** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
+ "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
+ /***** tileno, */
+ tileno, tpno,
+ startpack,
+ stoppack,
+ /***** j2k->cstr_info->tile[tileno].packet[startpack].start_pos, */
+ j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
+ /***** j2k->cstr_info->tile[tileno].packet[stoppack].end_pos, */
+ j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
+ pprot);
+
+ /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
+ j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
+ prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
+ j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
+
+ /*
+ particular case: if this is the last header and the last packet,
+ then it is better to protect even the EOC marker
+ */
+ /****** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
+ (stoppack == (j2k->cstr_info->num - 1))) */
+ if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
+ (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
+ (stoppack == last_tp_pack))
+ /* add the EOC len */
+ prot_len += 2;
+
+ /* let's add the EPBs */
+ Psot += jpwl_epbs_add(
+ j2k, /* J2K handle */
+ jwmarker, /* pointer to JPWL markers list */
+ &jwmarker_num, /* pointer to the number of current markers */
+ OPJ_FALSE, /* latest */
+ OPJ_TRUE, /* packed */
+ OPJ_FALSE, /* inside MH */
+ &epb_index, /* pointer to EPB index */
+ pprot, /* protection type */
+ /****** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001, */ /* position */
+ (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
+ tileno, /* number of tile */
+ 0, /* length of pre-data */
+ prot_len /*4000*/ /* length of post-data */
+ );
+ }
+
+ startpack = packno;
+ pprot = j2k->cp->pprot[packspec++];
+ }
+
+ /*printf("Tile %02d, pack %02d ==> %d\n", tileno, packno, pprot);*/
+
+ }
+
+ /* we are at the end: print the remaining spec */
+ stoppack = packno - 1;
+ if (pprot >= 0) {
+
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ /**** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
+ "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
+ /**** tileno, */
+ tileno, tpno,
+ startpack,
+ stoppack,
+ /***** j2k->image_info->tile[tileno].packet[startpack].start_pos,
+ j2k->image_info->tile[tileno].packet[stoppack].end_pos, */
+ j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
+ j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
+ pprot);
+
+ /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
+ j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
+ prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
+ j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
+
+ /*
+ particular case: if this is the last header and the last packet,
+ then it is better to protect even the EOC marker
+ */
+ /***** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
+ (stoppack == (j2k->cstr_info->num - 1))) */
+ if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
+ (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
+ (stoppack == last_tp_pack))
+ /* add the EOC len */
+ prot_len += 2;
+
+ /* let's add the EPBs */
+ Psot += jpwl_epbs_add(
+ j2k, /* J2K handle */
+ jwmarker, /* pointer to JPWL markers list */
+ &jwmarker_num, /* pointer to the number of current markers */
+ OPJ_TRUE, /* latest */
+ OPJ_TRUE, /* packed */
+ OPJ_FALSE, /* inside MH */
+ &epb_index, /* pointer to EPB index */
+ pprot, /* protection type */
+ /***** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001,*/ /* position */
+ (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
+ tileno, /* number of tile */
+ 0, /* length of pre-data */
+ prot_len /*4000*/ /* length of post-data */
+ );
+ }
+
+ /* we can now check if the TPH EPB was really the last one */
+ if (tph_epb && (epb_index == 1)) {
+ /* set the TPH EPB to be the last one in current header */
+ tph_epb->Depb |= (unsigned char) ((OPJ_TRUE & 0x0001) << 6);
+ tph_epb = NULL;
+ }
+
+ /* write back Psot */
+ cio_seek(cio, Psotp);
+ cio_write(cio, Psot, 4);
+
+ }
+
+ };
+
+ /* reset the position */
+ cio_seek(cio, ciopos);
+
+}
+
+void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
+
+ int mm;
+ unsigned long int old_size = j2k->cstr_info->codestream_size;
+ unsigned long int new_size = old_size;
+ int /*ciopos = cio_tell(cio),*/ soc_pos = j2k->cstr_info->main_head_start;
+ unsigned char *jpwl_buf, *orig_buf;
+ unsigned long int orig_pos;
+ double epbcoding_time = 0.0, esdcoding_time = 0.0;
+ (void)image;
+
+ /* Order JPWL markers according to their wishlist position */
+ qsort((void *) jwmarker, (size_t) jwmarker_num, sizeof (jpwl_marker_t), jpwl_markcomp);
+
+ /* compute markers total size */
+ for (mm = 0; mm < jwmarker_num; mm++) {
+ /*printf("%x, %d, %.10f, %d long\n", jwmarker[mm].id, jwmarker[mm].pos,
+ jwmarker[mm].dpos, jwmarker[mm].len);*/
+ new_size += jwmarker[mm].len + 2;
+ }
+
+ /* allocate a new buffer of proper size */
+ if (!(jpwl_buf = (unsigned char *) opj_malloc((size_t) (new_size + soc_pos) * sizeof(unsigned char)))) {
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for JPWL codestream buffer\n");
+ exit(1);
+ };
+
+ /* copy the jp2 part, if any */
+ orig_buf = jpwl_buf;
+ memcpy(jpwl_buf, cio->buffer, soc_pos);
+ jpwl_buf += soc_pos;
+
+ /* cycle through markers */
+ orig_pos = soc_pos + 0; /* start from the beginning */
+ cio_seek(cio, soc_pos + 0); /* rewind the original */
+ for (mm = 0; mm < jwmarker_num; mm++) {
+
+ /*
+ need to copy a piece of the original codestream
+ if there is such
+ */
+ memcpy(jpwl_buf, cio_getbp(cio), jwmarker[mm].pos - orig_pos);
+ jpwl_buf += jwmarker[mm].pos - orig_pos;
+ orig_pos = jwmarker[mm].pos;
+ cio_seek(cio, orig_pos);
+
+ /*
+ then write down the marker
+ */
+ switch (jwmarker[mm].id) {
+
+ case J2K_MS_EPB:
+ jpwl_epb_write(j2k, jwmarker[mm].m.epbmark, jpwl_buf);
+ break;
+
+ case J2K_MS_EPC:
+ jpwl_epc_write(j2k, jwmarker[mm].m.epcmark, jpwl_buf);
+ break;
+
+ case J2K_MS_ESD:
+ jpwl_esd_write(j2k, jwmarker[mm].m.esdmark, jpwl_buf);
+ break;
+
+ case J2K_MS_RED:
+ memset(jpwl_buf, 0, jwmarker[mm].len + 2); /* placeholder */
+ break;
+
+ default:
+ break;
+ };
+
+ /* we update the markers struct */
+ if (j2k->cstr_info)
+ j2k->cstr_info->marker[j2k->cstr_info->marknum - 1].pos = (jpwl_buf - orig_buf);
+
+ /* we set the marker dpos to the new position in the JPWL codestream */
+ jwmarker[mm].dpos = (double) (jpwl_buf - orig_buf);
+
+ /* advance JPWL buffer position */
+ jpwl_buf += jwmarker[mm].len + 2;
+
+ }
+
+ /* finish remaining original codestream */
+ memcpy(jpwl_buf, cio_getbp(cio), old_size - (orig_pos - soc_pos));
+ jpwl_buf += old_size - (orig_pos - soc_pos);
+ cio_seek(cio, soc_pos + old_size);
+
+ /*
+ update info file based on added markers
+ */
+ if (!jpwl_update_info(j2k, jwmarker, jwmarker_num))
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not update OPJ cstr_info structure\n");
+
+ /* now we need to repass some markers and fill their data fields */
+
+ /* first of all, DL and Pcrc in EPCs */
+ for (mm = 0; mm < jwmarker_num; mm++) {
+
+ /* find the EPCs */
+ if (jwmarker[mm].id == J2K_MS_EPC) {
+
+ int epc_pos = (int) jwmarker[mm].dpos, pp;
+ unsigned short int mycrc = 0x0000;
+
+ /* fix and fill the DL field */
+ jwmarker[mm].m.epcmark->DL = new_size;
+ orig_buf[epc_pos + 6] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 24);
+ orig_buf[epc_pos + 7] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 16);
+ orig_buf[epc_pos + 8] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 8);
+ orig_buf[epc_pos + 9] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 0);
+
+ /* compute the CRC field (excluding itself) */
+ for (pp = 0; pp < 4; pp++)
+ jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
+ for (pp = 6; pp < (jwmarker[mm].len + 2); pp++)
+ jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
+
+ /* fix and fill the CRC */
+ jwmarker[mm].m.epcmark->Pcrc = mycrc;
+ orig_buf[epc_pos + 4] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 8);
+ orig_buf[epc_pos + 5] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 0);
+
+ }
+ }
+
+ /* then, sensitivity data in ESDs */
+ esdcoding_time = opj_clock();
+ for (mm = 0; mm < jwmarker_num; mm++) {
+
+ /* find the ESDs */
+ if (jwmarker[mm].id == J2K_MS_ESD) {
+
+ /* remember that they are now in a new position (dpos) */
+ int esd_pos = (int) jwmarker[mm].dpos;
+
+ jpwl_esd_fill(j2k, jwmarker[mm].m.esdmark, &orig_buf[esd_pos]);
+
+ }
+
+ }
+ esdcoding_time = opj_clock() - esdcoding_time;
+ if (j2k->cp->esd_on)
+ opj_event_msg(j2k->cinfo, EVT_INFO, "ESDs sensitivities computed in %f s\n", esdcoding_time);
+
+ /* finally, RS or CRC parity in EPBs */
+ epbcoding_time = opj_clock();
+ for (mm = 0; mm < jwmarker_num; mm++) {
+
+ /* find the EPBs */
+ if (jwmarker[mm].id == J2K_MS_EPB) {
+
+ /* remember that they are now in a new position (dpos) */
+ int nn, accum_len;
+
+ /* let's see how many EPBs are following this one, included itself */
+ /* for this to work, we suppose that the markers are correctly ordered */
+ /* and, overall, that they are in packed mode inside headers */
+ accum_len = 0;
+ for (nn = mm; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
+ (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
+ accum_len += jwmarker[nn].m.epbmark->Lepb + 2;
+
+ /* fill the current (first) EPB with post-data starting from the computed position */
+ jpwl_epb_fill(j2k, jwmarker[mm].m.epbmark, &orig_buf[(int) jwmarker[mm].dpos],
+ &orig_buf[(int) jwmarker[mm].dpos + accum_len]);
+
+ /* fill the remaining EPBs in the header with post-data starting from the last position */
+ for (nn = mm + 1; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
+ (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
+ jpwl_epb_fill(j2k, jwmarker[nn].m.epbmark, &orig_buf[(int) jwmarker[nn].dpos], NULL);
+
+ /* skip all the processed EPBs */
+ mm = nn - 1;
+ }
+
+ }
+ epbcoding_time = opj_clock() - epbcoding_time;
+ if (j2k->cp->epb_on)
+ opj_event_msg(j2k->cinfo, EVT_INFO, "EPBs redundancy computed in %f s\n", epbcoding_time);
+
+ /* free original cio buffer and set it to the JPWL one */
+ opj_free(cio->buffer);
+ cio->cinfo = cio->cinfo; /* no change */
+ cio->openmode = cio->openmode; /* no change */
+ cio->buffer = orig_buf;
+ cio->length = new_size + soc_pos;
+ cio->start = cio->buffer;
+ cio->end = cio->buffer + cio->length;
+ cio->bp = cio->buffer;
+ cio_seek(cio, soc_pos + new_size);
+
+}
+
+
+void j2k_read_epc(opj_j2k_t *j2k) {
+ unsigned long int DL, Lepcp, Pcrcp, l;
+ unsigned short int Lepc, Pcrc = 0x0000;
+ unsigned char Pepc;
+ opj_cio_t *cio = j2k->cio;
+ const char *ans1;
+
+ /* Simply read the EPC parameters */
+ Lepcp = cio_tell(cio);
+ Lepc = cio_read(cio, 2);
+ Pcrcp = cio_tell(cio);
+ cio_skip(cio, 2); /* Pcrc */
+ DL = cio_read(cio, 4);
+ Pepc = cio_read(cio, 1);
+
+ /* compute Pcrc */
+ cio_seek(cio, Lepcp - 2);
+
+ /* Marker */
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+
+ /* Length */
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+
+ /* skip Pcrc */
+ cio_skip(cio, 2);
+
+ /* read all remaining */
+ for (l = 4; l < Lepc; l++)
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+
+ /* check Pcrc with the result */
+ cio_seek(cio, Pcrcp);
+ ans1 = (Pcrc == (unsigned short int) cio_read(cio, 2)) ? "crc-ok" : "crc-ko";
+
+ /* now we write them to screen */
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "EPC(%u,%d): %s, DL=%d%s %s %s\n",
+ Lepcp - 2,
+ Lepc,
+ ans1,
+ DL, /* data length this EPC is referring to */
+ (Pepc & 0x10) ? ", esd" : "", /* ESD is present */
+ (Pepc & 0x20) ? ", red" : "", /* RED is present */
+ (Pepc & 0x40) ? ", epb" : ""); /* EPB is present */
+
+ cio_seek(cio, Lepcp + Lepc);
+}
+
+void j2k_write_epc(opj_j2k_t *j2k) {
+
+ unsigned long int DL, Lepcp, Pcrcp, l;
+ unsigned short int Lepc, Pcrc;
+ unsigned char Pepc;
+
+ opj_cio_t *cio = j2k->cio;
+
+ cio_write(cio, J2K_MS_EPC, 2); /* EPC */
+ Lepcp = cio_tell(cio);
+ cio_skip(cio, 2);
+
+ /* CRC-16 word of the EPC */
+ Pcrc = 0x0000; /* initialize */
+ Pcrcp = cio_tell(cio);
+ cio_write(cio, Pcrc, 2); /* Pcrc placeholder*/
+
+ /* data length of the EPC protection domain */
+ DL = 0x00000000; /* we leave this set to 0, as if the information is not available */
+ cio_write(cio, DL, 4); /* DL */
+
+ /* jpwl capabilities */
+ Pepc = 0x00;
+ cio_write(cio, Pepc, 1); /* Pepc */
+
+ /* ID section */
+ /* no ID's, as of now */
+
+ Lepc = (unsigned short) (cio_tell(cio) - Lepcp);
+ cio_seek(cio, Lepcp);
+ cio_write(cio, Lepc, 2); /* Lepc */
+
+ /* compute Pcrc */
+ cio_seek(cio, Lepcp - 2);
+
+ /* Marker */
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+
+ /* Length */
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+
+ /* skip Pcrc */
+ cio_skip(cio, 2);
+
+ /* read all remaining */
+ for (l = 4; l < Lepc; l++)
+ jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
+
+ /* fill Pcrc with the result */
+ cio_seek(cio, Pcrcp);
+ cio_write(cio, Pcrc, 2);
+
+ cio_seek(cio, Lepcp + Lepc);
+
+ /* marker struct update */
+ j2k_add_marker(j2k->cstr_info, J2K_MS_EPC, Lepcp - 2, Lepc + 2);
+
+}
+
+void j2k_read_epb(opj_j2k_t *j2k) {
+ unsigned long int LDPepb, Pepb;
+ unsigned short int Lepb;
+ unsigned char Depb;
+ char str1[25] = "";
+ opj_bool status;
+ static opj_bool first_in_tph = OPJ_TRUE;
+ int type, pre_len, post_len;
+ static unsigned char *redund = NULL;
+
+ opj_cio_t *cio = j2k->cio;
+
+ /* B/W = 45, RGB = 51 */
+ /* SIZ SIZ_FIELDS SIZ_COMPS FOLLOWING_MARKER */
+ int skipnum = 2 + 38 + 3 * j2k->cp->exp_comps + 2;
+
+ if (j2k->cp->correct) {
+
+ /* go back to EPB marker value */
+ cio_seek(cio, cio_tell(cio) - 2);
+
+ /* we need to understand where we are */
+ if (j2k->state == J2K_STATE_MH) {
+ /* we are in MH */
+ type = 0; /* MH */
+ pre_len = skipnum; /* SOC+SIZ */
+ post_len = -1; /* auto */
+
+ } else if ((j2k->state == J2K_STATE_TPH) && first_in_tph) {
+ /* we are in TPH */
+ type = 1; /* TPH */
+ pre_len = 12; /* SOC+SIZ */
+ first_in_tph = OPJ_FALSE;
+ post_len = -1; /* auto */
+
+ } else {
+ /* we are elsewhere */
+ type = 2; /* other */
+ pre_len = 0; /* nada */
+ post_len = -1; /* auto */
+
+ }
+
+ /* call EPB corrector */
+ /*printf("before %x, ", redund);*/
+ status = jpwl_epb_correct(j2k, /* J2K decompressor handle */
+ cio->bp, /* pointer to EPB in codestream buffer */
+ type, /* EPB type: MH */
+ pre_len, /* length of pre-data */
+ post_len, /* length of post-data: -1 means auto */
+ NULL, /* do everything auto */
+ &redund
+ );
+ /*printf("after %x\n", redund);*/
+
+ /* Read the (possibly corrected) EPB parameters */
+ cio_skip(cio, 2);
+ Lepb = cio_read(cio, 2);
+ Depb = cio_read(cio, 1);
+ LDPepb = cio_read(cio, 4);
+ Pepb = cio_read(cio, 4);
+
+ if (!status) {
+
+ opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL correction could not be performed\n");
+
+ /* advance to EPB endpoint */
+ cio_skip(cio, Lepb + 2);
+
+ return;
+ }
+
+ /* last in current header? */
+ if (Depb & 0x40) {
+ redund = NULL; /* reset the pointer to L4 buffer */
+ first_in_tph = OPJ_TRUE;
+ }
+
+ /* advance to EPB endpoint */
+ cio_skip(cio, Lepb - 11);
+
+ } else {
+
+ /* Simply read the EPB parameters */
+ Lepb = cio_read(cio, 2);
+ Depb = cio_read(cio, 1);
+ LDPepb = cio_read(cio, 4);
+ Pepb = cio_read(cio, 4);
+
+ /* What does Pepb tells us about the protection method? */
+ if (((Pepb & 0xF0000000) >> 28) == 0)
+ sprintf(str1, "pred"); /* predefined */
+ else if (((Pepb & 0xF0000000) >> 28) == 1)
+ sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */
+ else if (((Pepb & 0xF0000000) >> 28) == 2)
+ sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */
+ else if (Pepb == 0xFFFFFFFF)
+ sprintf(str1, "nometh"); /* RS mode */
+ else
+ sprintf(str1, "unknown"); /* unknown */
+
+ /* Now we write them to screen */
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "EPB(%d): (%sl, %sp, %u), %lu, %s\n",
+ cio_tell(cio) - 13,
+ (Depb & 0x40) ? "" : "n", /* latest EPB or not? */
+ (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */
+ (Depb & 0x3F), /* EPB index value */
+ LDPepb, /*length of the data protected by the EPB */
+ str1); /* protection method */
+
+ cio_skip(cio, Lepb - 11);
+ }
+}
+
+void j2k_write_epb(opj_j2k_t *j2k) {
+ unsigned long int LDPepb, Pepb, Lepbp;
+ unsigned short int Lepb;
+ unsigned char Depb;
+
+ opj_cio_t *cio = j2k->cio;
+
+ cio_write(cio, J2K_MS_EPB, 2); /* EPB */
+ Lepbp = cio_tell(cio);
+ cio_skip(cio, 2);
+
+ /* EPB style */
+ Depb = 0x00; /* test */
+ cio_write(cio, Depb, 1); /* Depb */
+
+ /* length of the data to be protected by this EPB */
+ LDPepb = 0x00000000; /* test */
+ cio_write(cio, LDPepb, 4); /* LDPepb */
+
+ /* next error correction tool */
+ Pepb = 0x00000000; /* test */
+ cio_write(cio, Pepb, 4); /* Pepb */
+
+ /* EPB data */
+ /* no data, as of now */
+
+ Lepb = (unsigned short) (cio_tell(cio) - Lepbp);
+ cio_seek(cio, Lepbp);
+ cio_write(cio, Lepb, 2); /* Lepb */
+
+ cio_seek(cio, Lepbp + Lepb);
+
+ /* marker struct update */
+ j2k_add_marker(j2k->cstr_info, J2K_MS_EPB, Lepbp - 2, Lepb + 2);
+}
+
+void j2k_read_esd(opj_j2k_t *j2k) {
+ unsigned short int Lesd, Cesd;
+ unsigned char Pesd;
+
+ int cesdsize = (j2k->image->numcomps >= 257) ? 2 : 1;
+
+ char str1[4][4] = {"p", "br", "pr", "res"};
+ char str2[8][8] = {"res", "mse", "mse-r", "psnr", "psnr-i", "maxerr", "tse", "res"};
+
+ opj_cio_t *cio = j2k->cio;
+
+ /* Simply read the ESD parameters */
+ Lesd = cio_read(cio, 2);
+ Cesd = cio_read(cio, cesdsize);
+ Pesd = cio_read(cio, 1);
+
+ /* Now we write them to screen */
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "ESD(%d): c%d, %s, %s, %s, %s, %s\n",
+ cio_tell(cio) - (5 + cesdsize),
+ Cesd, /* component number for this ESD */
+ str1[(Pesd & (unsigned char) 0xC0) >> 6], /* addressing mode */
+ str2[(Pesd & (unsigned char) 0x38) >> 3], /* sensitivity type */
+ ((Pesd & (unsigned char) 0x04) >> 2) ? "2Bs" : "1Bs",
+ ((Pesd & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba",
+ (Pesd & (unsigned char) 0x01) ? "avgc" : "");
+
+ cio_skip(cio, Lesd - (3 + cesdsize));
+}
+
+void j2k_read_red(opj_j2k_t *j2k) {
+ unsigned short int Lred;
+ unsigned char Pred;
+ char str1[4][4] = {"p", "br", "pr", "res"};
+
+ opj_cio_t *cio = j2k->cio;
+
+ /* Simply read the RED parameters */
+ Lred = cio_read(cio, 2);
+ Pred = cio_read(cio, 1);
+
+ /* Now we write them to screen */
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "RED(%d): %s, %dc, %s, %s\n",
+ cio_tell(cio) - 5,
+ str1[(Pred & (unsigned char) 0xC0) >> 6], /* addressing mode */
+ (Pred & (unsigned char) 0x38) >> 3, /* corruption level */
+ ((Pred & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba", /* address range */
+ (Pred & (unsigned char) 0x01) ? "errs" : "free"); /* error free? */
+
+ cio_skip(cio, Lred - 3);
+}
+
+opj_bool jpwl_check_tile(opj_j2k_t *j2k, opj_tcd_t *tcd, int tileno) {
+
+#ifdef oerhgierhgvhreit4u
+ /*
+ we navigate through the tile and find possible invalid parameters:
+ this saves a lot of crashes!!!!!
+ */
+ int compno, resno, precno, /*layno,*/ bandno, blockno;
+ int numprecincts, numblocks;
+
+ /* this is the selected tile */
+ opj_tcd_tile_t *tile = &(tcd->tcd_image->tiles[tileno]);
+
+ /* will keep the component */
+ opj_tcd_tilecomp_t *comp = NULL;
+
+ /* will keep the resolution */
+ opj_tcd_resolution_t *res;
+
+ /* will keep the subband */
+ opj_tcd_band_t *band;
+
+ /* will keep the precinct */
+ opj_tcd_precinct_t *prec;
+
+ /* will keep the codeblock */
+ opj_tcd_cblk_t *block;
+
+ /* check all tile components */
+ for (compno = 0; compno < tile->numcomps; compno++) {
+ comp = &(tile->comps[compno]);
+
+ /* check all component resolutions */
+ for (resno = 0; resno < comp->numresolutions; resno++) {
+ res = &(comp->resolutions[resno]);
+ numprecincts = res->pw * res->ph;
+
+ /* check all the subbands */
+ for (bandno = 0; bandno < res->numbands; bandno++) {
+ band = &(res->bands[bandno]);
+
+ /* check all the precincts */
+ for (precno = 0; precno < numprecincts; precno++) {
+ prec = &(band->precincts[precno]);
+ numblocks = prec->ch * prec->cw;
+
+ /* check all the codeblocks */
+ for (blockno = 0; blockno < numblocks; blockno++) {
+ block = &(prec->cblks[blockno]);
+
+ /* x-origin is invalid */
+ if ((block->x0 < prec->x0) || (block->x0 > prec->x1)) {
+ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+ "JPWL: wrong x-cord of block origin %d => x-prec is (%d, %d)\n",
+ block->x0, prec->x0, prec->x1);
+ if (!JPWL_ASSUME || JPWL_ASSUME)
+ return OPJ_FALSE;
+ };
+ }
+ }
+ }
+ }
+ }
+
+#else
+ (void)j2k;
+ (void)tcd;
+ (void)tileno;
+#endif
+
+ return OPJ_TRUE;
+}
+
+/*@}*/
+
+#endif /* USE_JPWL */
+
+
+#ifdef USE_JPSEC
+
+/** @defgroup JPSEC JPSEC - JPEG-2000 Part 8 (JPSEC) codestream manager */
+/*@{*/
+
+
+/** @name Local static functions */
+/*@{*/
+
+void j2k_read_sec(opj_j2k_t *j2k) {
+ unsigned short int Lsec;
+
+ opj_cio_t *cio = j2k->cio;
+
+ /* Simply read the SEC length */
+ Lsec = cio_read(cio, 2);
+
+ /* Now we write them to screen */
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "SEC(%d)\n",
+ cio_tell(cio) - 2
+ );
+
+ cio_skip(cio, Lsec - 2);
+}
+
+void j2k_write_sec(opj_j2k_t *j2k) {
+ unsigned short int Lsec = 24;
+ int i;
+
+ opj_cio_t *cio = j2k->cio;
+
+ cio_write(cio, J2K_MS_SEC, 2); /* SEC */
+ cio_write(cio, Lsec, 2);
+
+ /* write dummy data */
+ for (i = 0; i < Lsec - 2; i++)
+ cio_write(cio, 0, 1);
+}
+
+void j2k_read_insec(opj_j2k_t *j2k) {
+ unsigned short int Linsec;
+
+ opj_cio_t *cio = j2k->cio;
+
+ /* Simply read the INSEC length */
+ Linsec = cio_read(cio, 2);
+
+ /* Now we write them to screen */
+ opj_event_msg(j2k->cinfo, EVT_INFO,
+ "INSEC(%d)\n",
+ cio_tell(cio) - 2
+ );
+
+ cio_skip(cio, Linsec - 2);
+}
+
+
+/*@}*/
+
+/*@}*/
+
+#endif /* USE_JPSEC */
+