2085 lines
58 KiB
C
2085 lines
58 KiB
C
/*
|
|
* Copyright 2004-2005 Andrea Betti and Michele Massarelli
|
|
* Copyright 2004-2005 DIEI, University of Perugia
|
|
*
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
|
|
/* questa è un' estensione della libreria dell'openjpeg in grado di implementare
|
|
* la parte 11 dello standard JPEG2000 ossia il JPWL
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <setjmp.h>
|
|
#include <conio.h>
|
|
#include <math.h>
|
|
#include "j2k.h"
|
|
#include "cio.h"
|
|
#include "jpw.h"
|
|
#include "rs.h"
|
|
|
|
// JPWL MARKERS
|
|
#define JPWL_MS_EPC 0xff68
|
|
#define JPWL_MS_EPB 0xff66
|
|
#define JPWL_MS_ESD 0xff67
|
|
#define JPWL_MS_RED 0xff69
|
|
|
|
|
|
//stati del codec
|
|
#define J2K_STATE_MHSOC 0x0001
|
|
#define J2K_STATE_MHSIZ 0x0002
|
|
#define J2K_STATE_MH 0x0004
|
|
#define J2K_STATE_TPHSOT 0x0008
|
|
#define J2K_STATE_TPH 0x0010
|
|
#define J2K_STATE_MT 0x0020
|
|
#define J2K_STATE_NEOC 0x0040
|
|
#define J2K_STATE_MHEPB 0x0080
|
|
#define J2K_STATE_TPHEPB 0x0100
|
|
|
|
//carica la struttura relativa ai parametri JPWL
|
|
extern JPWL_cp_t jpwl_cp;
|
|
extern int j2k_state;
|
|
extern j2k_cp_t *j2k_cp;
|
|
extern info_image info_IM;
|
|
|
|
static long crcSum;
|
|
static long pepbs[1000];
|
|
static int cont_epb=0;
|
|
static int scavalcato=0;
|
|
|
|
static int CrcT16[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};
|
|
|
|
static long CrcT32[256] = {0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
|
|
0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
|
|
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
|
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
|
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
|
|
0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
|
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
|
|
0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
|
|
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
|
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
|
|
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
|
|
0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
|
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
|
|
0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
|
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
|
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
|
|
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
|
|
0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
|
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
|
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
|
|
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
|
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
|
|
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
|
|
0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
|
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
|
|
0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
|
|
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
|
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
|
|
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
|
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
|
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
|
|
0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
|
|
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
|
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
|
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
|
|
0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
|
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
|
|
0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
|
|
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
|
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
|
|
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
|
|
0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
|
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
|
|
0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
|
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
|
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
|
|
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
|
|
0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
|
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
|
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
|
|
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
|
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
|
|
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
|
|
0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
|
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
|
|
0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
|
|
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
|
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
|
|
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
|
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
|
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
|
|
0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
|
|
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
|
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
|
|
|
|
|
|
/* inizializza i parametri relativi al JPWL *
|
|
* disabilitando le funzionalità */
|
|
|
|
void jpwl_cp_init(JPWL_cp_t *jpwl_cp){
|
|
jpwl_cp->JPWL_on = 0;
|
|
jpwl_cp->EPB_on = 0;
|
|
jpwl_cp->ESD_on = 0;
|
|
jpwl_cp->RED_on = 0;
|
|
jpwl_cp->info_tech_on = 0;
|
|
}
|
|
|
|
/****************************************************************************************
|
|
* *
|
|
* Marker JPWL *
|
|
* *
|
|
****************************************************************************************/
|
|
|
|
/* Scrive il marker segment EPC
|
|
version 0.1: in questa prima fase questo andrà subito dopo il SIZ */
|
|
|
|
void jpwl_write_EPC(){
|
|
int lenp, len, i;
|
|
char c, P_EPC = 0;
|
|
cio_write(JPWL_MS_EPC, 2);
|
|
lenp = cio_tell();
|
|
cio_skip(2);
|
|
// calcola il crc
|
|
cio_skip(2);
|
|
// per adesso lascio uno spazio vuoto (16 bit)
|
|
// CL settore di 32bit che indica la lungheza della codestream:
|
|
// per ora metto tutto uguale a zero (info non disponibile)
|
|
cio_write(0, 4);
|
|
// P_EPC indica se nella codestream saranno usati gli altri
|
|
// marker segment oppure tecniche informative aggiuntive
|
|
if (jpwl_cp.ESD_on)
|
|
P_EPC += 0x10;
|
|
if (jpwl_cp.RED_on)
|
|
P_EPC += 0x20;
|
|
if (jpwl_cp.EPB_on)
|
|
P_EPC += 0x40;
|
|
if (jpwl_cp.info_tech_on)
|
|
P_EPC += 0x80;
|
|
cio_write(P_EPC, 1);
|
|
//scrivo i Pepb
|
|
|
|
if(jpwl_cp.EPB_on)
|
|
JPWL_write_Pepbs(NULL,0);
|
|
|
|
|
|
|
|
|
|
/* Al momento non esistono tecniche informative aggiuntive per richiamarle
|
|
* opereremo in questo modo:
|
|
* 0) dovrò inserire nella struttura jpwl_cp_t un campo contenente un puntatore
|
|
* ad un array che conterrà gli ID delle tecniche informative da usare;
|
|
* 1) conrollo il campo info_tech_on;
|
|
* 2) eseguo delle funzioni da inserire nel file jpw.c e jpw.h relative alle
|
|
* tecniche informative desiderate; tali funzioni dovranno preoccuparsi di
|
|
* creare i campi corretti nel marker segment.
|
|
* if( jpwl_cp->info_tech_on){
|
|
* qui inserirò i comandi desiderati
|
|
* }
|
|
*/
|
|
len = cio_tell() - lenp;
|
|
cio_seek(lenp);
|
|
cio_write(len, 2);
|
|
// calcola il crc
|
|
cio_skip(-4);
|
|
ResetCRC();
|
|
for (i=0; i<4; i++){
|
|
c = cio_read(1);
|
|
UpdateCRC16(c);
|
|
}
|
|
cio_skip(2);
|
|
for (i=6; i<(len + 2); i++){
|
|
c = cio_read(1);
|
|
UpdateCRC16(c);
|
|
}
|
|
cio_seek(lenp + 2);
|
|
cio_write(crcSum, 2);
|
|
cio_seek(lenp + len);
|
|
|
|
}
|
|
|
|
|
|
void jpwl_write_EPC_fin(unsigned long CL, long *pepbs, int num_epb){
|
|
int lenp, len, i;
|
|
unsigned long len_codestr;
|
|
char c, P_EPC = 0;
|
|
cio_write(JPWL_MS_EPC, 2);
|
|
lenp = cio_tell();
|
|
cio_skip(2);
|
|
// calcola il crc
|
|
cio_skip(2);
|
|
// per adesso lascio uno spazio vuoto (16 bit)
|
|
// CL settore di 32bit che indica la lungheza della codestream:
|
|
// per ora metto tutto uguale a zero (info non disponibile)
|
|
cio_write(0, 4);
|
|
// P_EPC indica se nella codestream saranno usati gli altri
|
|
// marker segment oppure tecniche informative aggiuntive
|
|
if (jpwl_cp.ESD_on)
|
|
P_EPC += 0x10;
|
|
if (jpwl_cp.RED_on)
|
|
P_EPC += 0x20;
|
|
if (jpwl_cp.EPB_on)
|
|
P_EPC += 0x40;
|
|
if (jpwl_cp.info_tech_on)
|
|
P_EPC += 0x80;
|
|
cio_write(P_EPC, 1);
|
|
//scrivo i Pepb
|
|
|
|
if(jpwl_cp.EPB_on)
|
|
JPWL_write_Pepbs(pepbs, num_epb);
|
|
|
|
|
|
|
|
|
|
/* Al momento non esistono tecniche informative aggiuntive per richiamarle
|
|
* opereremo in questo modo:
|
|
* 0) dovrò inserire nella struttura jpwl_cp_t un campo contenente un puntatore
|
|
* ad un array che conterrà gli ID delle tecniche informative da usare;
|
|
* 1) conrollo il campo info_tech_on;
|
|
* 2) eseguo delle funzioni da inserire nel file jpw.c e jpw.h relative alle
|
|
* tecniche informative desiderate; tali funzioni dovranno preoccuparsi di
|
|
* creare i campi corretti nel marker segment.
|
|
* if( jpwl_cp->info_tech_on){
|
|
* qui inserirò i comandi desiderati
|
|
* }
|
|
*/
|
|
len = cio_tell() - lenp;
|
|
cio_seek(lenp);
|
|
cio_write(len, 2);
|
|
//scrivo la lunghezza della codestream
|
|
cio_skip(2);
|
|
len_codestr = CL + len + 2;
|
|
cio_write(len_codestr, 4);
|
|
// calcola il crc
|
|
cio_skip(-10);
|
|
ResetCRC();
|
|
for (i=0; i<4; i++){
|
|
c = cio_read(1);
|
|
UpdateCRC16(c);
|
|
}
|
|
cio_skip(2);
|
|
for (i=6; i<(len + 2); i++){
|
|
c = cio_read(1);
|
|
UpdateCRC16(c);
|
|
}
|
|
cio_seek(lenp + 2);
|
|
cio_write(crcSum, 2);
|
|
cio_seek(lenp + len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void JPWL_write_EPB(char *buf, unsigned long LDPepb, unsigned long Pepb, unsigned char Depb){
|
|
int *alpha_to, *index_of, *gg, *data_, *bb;
|
|
unsigned long i=0;
|
|
unsigned int len = 11, lenp, scrivi_pb, cont, leggi, tenta=0;
|
|
char pos_epb;
|
|
unsigned data_unprot = 0, RS = 0;
|
|
int n1, n2, k1, k2, j, n=255, k, CRC = 0, go_back; // 0 = disabilitato, 1 = CRC CCITT 16 bit, 2 = Ethernet CRC 32 bit
|
|
//prova
|
|
/*FILE *f;
|
|
FILE *fp;*/
|
|
|
|
|
|
cio_write(JPWL_MS_EPB, 2);
|
|
lenp = cio_tell();
|
|
/* determino len_epb e i parametri di codifica*/
|
|
pos_epb= Depb & 0x3F;
|
|
if ((j2k_state == J2K_STATE_MH) && !(pos_epb)){ // sto scrivendo il primo epb del mh
|
|
|
|
n1=160;
|
|
k1=64;
|
|
go_back =lenp + 11;
|
|
len += (n1 - k1)*(unsigned int)ceil((double)go_back/k1);
|
|
} else {if ((j2k_state == J2K_STATE_TPH) && !(pos_epb)&& !(scavalcato)){ // primo epb di un tph
|
|
n1=80;
|
|
k1=go_back=25;
|
|
len += 55;
|
|
|
|
} else { // altro epb
|
|
n1=40;
|
|
k1=go_back=13;
|
|
len += 27;
|
|
//tenta=1;
|
|
}
|
|
}
|
|
if (!Pepb) { // per codificare i dati seguenti uso lo stesso codice di prima
|
|
RS = 1;
|
|
n2 = n1;
|
|
k2 = k1;
|
|
len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
|
|
|
|
} else{
|
|
if (Pepb == 0xffffffff)
|
|
data_unprot=1;
|
|
else {if ((Pepb >> 28)== 1){
|
|
if ((Pepb & 0x00000001)){
|
|
CRC = 2;
|
|
len += 4;
|
|
} else {
|
|
CRC = 1;
|
|
len +=2;
|
|
}
|
|
} else {if ((Pepb >> 28)== 2){
|
|
n2 = ((Pepb & 0x0000ff00)>> 8);
|
|
k2 = (Pepb & 0x000000ff);
|
|
RS = 1;
|
|
len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cio_write(len, 2); // Lepb
|
|
cio_write(Depb, 1); //Depb
|
|
cio_write((LDPepb & 0xffff0000) >> 16, 2); //LDPepb
|
|
cio_write((LDPepb & 0x0000ffff), 2);
|
|
cio_write((Pepb & 0xffff0000) >> 16, 2); //Pepb
|
|
cio_write((Pepb & 0x0000ffff), 2);
|
|
//printf("start\n");
|
|
|
|
// devi implementare il codice rs per la protezione dell'epb
|
|
// cio_write(0, (int) ceil((lenp+11)*(n1 - k1)/k1));
|
|
if(!(alpha_to=(int *) calloc(256,sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma1\n ");
|
|
|
|
if(!(index_of=(int *) calloc(256,sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma2\n ");
|
|
|
|
if(!(gg=(int *) calloc((n1 - k1 +1),sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma3\n ");
|
|
|
|
k = 255-(n1-k1);
|
|
|
|
if(!(data_=(int *) calloc(k, sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma4\n ");
|
|
|
|
if(!(bb=(int *) calloc((n1 - k1),sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma5\n ");
|
|
|
|
generate_gf(alpha_to, index_of);
|
|
|
|
gen_poly(k, alpha_to, index_of, gg);
|
|
|
|
scrivi_pb = cio_tell();
|
|
|
|
//prova
|
|
|
|
|
|
cio_skip(-go_back);
|
|
for (cont = 0; cont < (unsigned int) ceil((double)go_back/k1); cont++) {
|
|
for (j=0; j<k1; j++){
|
|
if (j+(cont*k1) <(unsigned int) go_back)
|
|
data_[j]= cio_read(1);
|
|
else data_[j] = 0; //padding
|
|
}
|
|
for (j=k1; j<k; j++) data_[j] = 0; // padding per la gestione di codici "accorciati"
|
|
|
|
leggi = cio_tell();
|
|
encode_rs(k,alpha_to, index_of, gg, bb, data_);
|
|
|
|
cio_seek(scrivi_pb);
|
|
for (j=0; j<(n1-k1); j++)
|
|
cio_write(bb[j], 1);
|
|
scrivi_pb = cio_tell();
|
|
cio_seek(leggi);
|
|
}
|
|
cio_seek(scrivi_pb);
|
|
|
|
free(alpha_to);
|
|
free(index_of);
|
|
free(gg);
|
|
free(data_);
|
|
free(bb);
|
|
|
|
/* protezione dei dati seguenti */
|
|
|
|
|
|
if (!data_unprot) {
|
|
if (CRC == 1){ //crc ccitt 16 bit questo è l'algo
|
|
ResetCRC();
|
|
for (i=0; i < LDPepb; i++){
|
|
UpdateCRC16(buf[i]);
|
|
}
|
|
cio_write(crcSum & 0xffff, 2);
|
|
}
|
|
if (CRC == 2){
|
|
/*per fare il crc32 occorre invertire i byte in ingresso, invertire il crc calcolato
|
|
e farne il complemento a 1*/
|
|
ResetCRC();
|
|
for (i=0; i < LDPepb; i++){
|
|
UpdateCRC32(reflectByte(buf[i]));
|
|
}
|
|
reflectCRC32();
|
|
crcSum ^= 0xffffffff;
|
|
cio_write((crcSum & 0xffff0000) >> 16, 2);
|
|
cio_write((crcSum & 0x0000ffff), 2);
|
|
}
|
|
if (RS) {
|
|
//printf("n2, k2: %d %d\n", n2, k2);
|
|
k = 255-(n2-k2);
|
|
|
|
if(!(alpha_to=(int *) malloc(256*sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma1\n ");
|
|
|
|
if(!(index_of=(int *) malloc(256*sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma2\n ");
|
|
|
|
if(!(gg=(int *) malloc((n2 - k2 +1)*sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma3\n ");
|
|
|
|
if(!(data_=(int *) malloc(k*sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma4\n ");
|
|
|
|
if(!(bb=(int *) malloc((n2 - k2)*sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma5\n ");
|
|
|
|
generate_gf(alpha_to, index_of);
|
|
|
|
gen_poly(k, alpha_to, index_of, gg);
|
|
//printf("num blocchi: %f\n", ceil((double)LDPepb/k2));
|
|
//printf("resto: %d\n", LDPepb%k2);
|
|
|
|
for (cont = 0; cont < (unsigned int)ceil((double)LDPepb/k2); cont++) {
|
|
|
|
for (j=0; j<k2; j++){
|
|
if (j+(cont*k2) < LDPepb)
|
|
data_[j]= 0x000000ff & buf[j+(cont*k2)]; //qualcuno dovrà spiegarmi il perchè!!!!
|
|
else data_[j] = 0; //padding
|
|
}
|
|
|
|
for (j=k2; j<k; j++) data_[j] = 0; // padding per la gestione di codici "accorciati"
|
|
//prova
|
|
/*if ((cont==(unsigned int)ceil((double)LDPepb/k2)-1)&&(tenta)){
|
|
f=fopen("data.txt","wb");
|
|
for(j=0; j<k; j++) fputc(data_[j], f);
|
|
fclose(f);
|
|
}*/
|
|
|
|
encode_rs(k, alpha_to, index_of, gg, bb, data_);
|
|
//prova
|
|
/*if ((cont==(unsigned int)ceil((double)LDPepb/k2)-1)&&(tenta)){
|
|
fp=fopen("parity.txt","wb");
|
|
for(j=0; j<(n2-k2); j++) fputc(bb[j], fp);
|
|
fclose(fp);
|
|
}*/
|
|
|
|
for (j=0; j<(n2-k2); j++){
|
|
cio_write(bb[j], 1);
|
|
}
|
|
|
|
}
|
|
|
|
free(alpha_to);
|
|
free(index_of);
|
|
free(gg);
|
|
free(data_);
|
|
free(bb);
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void jpwl_write_ESD(char Pesd, int notil){
|
|
int i, ult, set, nb_pos, nb_sv, metric, mode, cont=0, npix, lev, start, end, temp, len, npack;
|
|
double **dMSE, **dPSNR, maxMSE, **PSNR, M, val, x;
|
|
|
|
//nuova versione!!
|
|
cio_write(JPWL_MS_ESD,2);
|
|
set = cio_tell();
|
|
cio_skip(2); //len
|
|
// faccio solo un esd medio relativo a tutte le componenti
|
|
if(info_IM.Comp < 257)
|
|
cio_write(0,1); //Cesd
|
|
else cio_write(0x0000,2);
|
|
cio_write(Pesd,1);
|
|
//determino i parametri per scrivere i dati dell'esd
|
|
nb_pos = (((Pesd & 0x02)>>1)==0) ? 2 : 4;
|
|
nb_sv = (((Pesd & 0x04)>>2)==0) ? 1 : 2;
|
|
metric = ((Pesd & 0x38)>>3);
|
|
mode = ((Pesd & 0xC0)>>6);
|
|
M = 65025;
|
|
// creo le matrici che conterranno i valori di deltaMSE e deltaPSNR
|
|
// in realtà spreco un po' di memoria nel caso in cui la scrivo nei tile...
|
|
dMSE = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double));
|
|
for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
|
|
dMSE[i]=(double*) malloc(info_IM.num *sizeof(double));
|
|
dPSNR = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double));
|
|
for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
|
|
dPSNR[i]=(double*) malloc(info_IM.num *sizeof(double));
|
|
PSNR = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double));
|
|
for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
|
|
PSNR[i]=(double*) malloc(info_IM.num * sizeof(double));
|
|
|
|
// a questo punto se notil=0 vuol dire che scrivo l'esd nel main header
|
|
// altrimenti notil indica il tile a cui mi riferisco
|
|
ult = (notil == 0) ? j2k_cp->th * j2k_cp->tw : notil;
|
|
if (notil != 0) notil--;
|
|
|
|
// calcolo di dPSNR, dMSE e PSNR
|
|
// nuova routine più snella!!
|
|
for (i = notil; i < ult; i++){
|
|
val = 0;
|
|
npix = info_IM.tile[i].nbpix;
|
|
maxMSE = info_IM.tile[i].distotile / npix;
|
|
for(npack=0; npack < (info_IM.num); npack++){
|
|
dMSE[i][npack] = info_IM.tile[i].packet[npack].disto / npix;
|
|
if (dMSE[i][npack]!=0){
|
|
val += dMSE[i][npack];
|
|
PSNR[i][npack] = (10 * log10(M/(maxMSE - val)));
|
|
x = (npack==0) ? 0 : PSNR[i][npack-1];
|
|
dPSNR[i][npack] = PSNR[i][npack] - x;
|
|
}
|
|
else {
|
|
dPSNR[i][npack] = 0;
|
|
PSNR[i][npack] = PSNR[i][npack-1];
|
|
}
|
|
}
|
|
}
|
|
|
|
//ora scrivo i valori di sensibilità in base alla metrica scelta
|
|
switch (metric){
|
|
case 0:
|
|
//relative error sensitivity: i lvelli di sensibilità coincidono con i layer (livello 0 = header)
|
|
//uso sette livelli di sensibilità relativa
|
|
switch (mode){
|
|
case 0:
|
|
//packet mode
|
|
|
|
for (i = notil; i < ult; i++){
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
if (dPSNR[i][npack]>10)
|
|
cio_write(1, 1);
|
|
else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
|
|
cio_write(2,1);
|
|
else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
|
|
cio_write(3,1);
|
|
else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
|
|
cio_write(4,1);
|
|
else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
|
|
cio_write(5,1);
|
|
else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
|
|
cio_write(6,1);
|
|
else
|
|
//(dPSNR[i][npack]<=1.7)
|
|
cio_write(7,1);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
//byte range mode
|
|
for (i = notil; i < ult; i++){
|
|
//inizializzazioni
|
|
lev = 0;
|
|
start = 0;
|
|
end = 1;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
temp=lev;
|
|
//determinazione dei livelli
|
|
if (dPSNR[i][npack]>10)
|
|
lev = 1;
|
|
else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
|
|
lev = 2;
|
|
else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
|
|
lev = 3;
|
|
else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
|
|
lev = 4;
|
|
else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
|
|
lev = 5;
|
|
else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
|
|
lev = 6;
|
|
else
|
|
//(dPSNR[i][npack]<=1.7)
|
|
lev = 7;
|
|
if (lev == temp){
|
|
end++;
|
|
continue;
|
|
} else {
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
|
|
cio_write(lev, nb_sv);
|
|
start = end;
|
|
end++;
|
|
}
|
|
}
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
|
|
cio_write(lev, nb_sv);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
//packet range mode
|
|
for (i = notil; i < ult; i++){
|
|
//inizializzazioni
|
|
lev = 0;
|
|
start = 0;
|
|
end = 1;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
temp=lev;
|
|
//determinazione dei livelli (catena di if-else-if)
|
|
if (dPSNR[i][npack]>10)
|
|
lev = 1;
|
|
else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
|
|
lev = 2;
|
|
else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
|
|
lev = 3;
|
|
else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
|
|
lev = 4;
|
|
else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
|
|
lev = 5;
|
|
else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
|
|
lev = 6;
|
|
else
|
|
//(dPSNR[i][npack]<=1.7)
|
|
lev = 7;
|
|
if (lev == temp){
|
|
end++;
|
|
continue;
|
|
} else {
|
|
cio_write(start, nb_pos);
|
|
cio_write(end-1, nb_pos);
|
|
cio_write(lev, nb_sv);
|
|
start = end;
|
|
end++;
|
|
}
|
|
}
|
|
cio_write(start, nb_pos);
|
|
cio_write(end - 1, nb_pos);
|
|
cio_write(lev, nb_sv);
|
|
}
|
|
|
|
break;
|
|
default:
|
|
printf("errore\n");
|
|
}
|
|
break;
|
|
case 1:
|
|
// MSE
|
|
switch (mode){
|
|
case 0:
|
|
//packet mode
|
|
for (i = notil; i < ult; i++){
|
|
npix = info_IM.tile[i].nbpix;
|
|
val = info_IM.tile[i].distotile / npix;
|
|
cio_write(d2pfp(val), nb_sv);
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
val -= dMSE[i][npack];
|
|
cio_write(d2pfp(val), nb_sv);
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
//byte range mode
|
|
//divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
|
|
for (i = notil; i < ult; i++){
|
|
npix = info_IM.tile[i].nbpix;
|
|
val = info_IM.tile[i].distotile / npix;
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
val -= dMSE[i][npack];
|
|
if (((npack+1) % 10)==0){
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
start = end+1;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case 2:
|
|
//packet range mode
|
|
//divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
|
|
for (i = notil; i < ult; i++){
|
|
npix = info_IM.tile[i].nbpix;
|
|
val = info_IM.tile[i].distotile / npix;
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
val -= dMSE[i][npack];
|
|
if (((npack+1) % 10)==0){
|
|
cio_write(start, nb_pos);
|
|
cio_write(end, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
start = end+1;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
cio_write(start, nb_pos);
|
|
cio_write(end-1, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
printf("errore\n");
|
|
}
|
|
|
|
break;
|
|
case 2:
|
|
// MSE reduction
|
|
switch (mode){
|
|
case 0:
|
|
//packet mode
|
|
for (i = notil; i < ult; i++)
|
|
for (npack=0; npack < (info_IM.num); npack++)
|
|
cio_write(d2pfp(dMSE[i][npack]), nb_sv);
|
|
|
|
break;
|
|
case 1:
|
|
//byte range mode
|
|
//scrivo la mse reduction media relativa ad un blocco di dieci pacchetti
|
|
for (i = notil; i < ult; i++){
|
|
val = 0;
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
val += dMSE[i][npack];
|
|
if (((npack+1) % 10)==0){
|
|
val /= 10;
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
start = end+1;
|
|
val = 0;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
val /= npack%10;
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
//packet range mode
|
|
//scrivo la mse reduction media relativa ad un blocco di dieci pacchetti
|
|
for (i = notil; i < ult; i++){
|
|
val = 0;
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
val += dMSE[i][npack];
|
|
if (((npack+1) % 10)==0){
|
|
val /= 10;
|
|
cio_write(start, nb_pos);
|
|
cio_write(end, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
start = end+1;
|
|
val = 0;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
val /= npack%10;
|
|
cio_write(start, nb_pos);
|
|
cio_write(end-1, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
printf("errore\n");
|
|
}
|
|
|
|
break;
|
|
case 3:
|
|
//PSNR
|
|
|
|
switch (mode){
|
|
case 0:
|
|
//packet mode
|
|
for (i = notil; i < ult; i++)
|
|
for (npack=0; npack < (info_IM.num); npack++)
|
|
cio_write(d2pfp(PSNR[i][npack]),nb_sv);
|
|
break;
|
|
case 1:
|
|
//byte range mode
|
|
//divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
|
|
for (i = notil; i < ult; i++){
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
if (((npack+1) % 10)==0){
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
//printf("start: %d\n",info_IM.tile[i].packet[start].start_pos);
|
|
cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
|
|
//printf("end: %d\n", info_IM.tile[i].packet[end].end_pos);
|
|
cio_write(d2pfp(PSNR[i][npack]), nb_sv);
|
|
start = end+1;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
//printf("start: %d\n",info_IM.tile[i].packet[start].start_pos);
|
|
cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
|
|
//printf("end: %d\n", info_IM.tile[i].packet[end-1].end_pos);
|
|
cio_write(d2pfp(PSNR[i][end-1]), nb_sv);
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
//packet range mode
|
|
//divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
|
|
for (i = notil; i < ult; i++){
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
if (((npack+1) % 10)==0){
|
|
cio_write(start, nb_pos);
|
|
cio_write(end, nb_pos);
|
|
cio_write(d2pfp(PSNR[i][npack]), nb_sv);
|
|
start = end+1;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
cio_write(start, nb_pos);
|
|
cio_write(end-1, nb_pos);
|
|
cio_write(d2pfp(PSNR[i][end-1]), nb_sv);
|
|
}
|
|
}
|
|
|
|
break;
|
|
default:
|
|
printf("errore\n");
|
|
}
|
|
|
|
break;
|
|
case 4:
|
|
//PSNR increases
|
|
|
|
switch (mode){
|
|
case 0:
|
|
//packet mode
|
|
for (i = notil; i < ult; i++)
|
|
for (npack=0; npack < (info_IM.num); npack++)
|
|
cio_write(d2pfp(dPSNR[i][npack]), nb_sv);
|
|
break;
|
|
case 1:
|
|
//byte range mode
|
|
//scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti
|
|
for (i = notil; i < ult; i++){
|
|
val = 0;
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
val += dPSNR[i][npack];
|
|
if (((npack+1) % 10)==0){
|
|
val /= 10;
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
start = end+1;
|
|
val = 0;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
val /= npack%10;
|
|
cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
|
|
cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
//packet range mode
|
|
//scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti
|
|
for (i = notil; i < ult; i++){
|
|
val = 0;
|
|
start = 0;
|
|
end = 0;
|
|
for (npack=0; npack < (info_IM.num); npack++){
|
|
val += dPSNR[i][npack];
|
|
if (((npack+1) % 10)==0){
|
|
val /= 10;
|
|
cio_write(start, nb_pos);
|
|
cio_write(end, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
start = end+1;
|
|
val = 0;
|
|
}
|
|
end++;
|
|
}
|
|
if (start != end){
|
|
val /= npack%10;
|
|
cio_write(start, nb_pos);
|
|
cio_write(end-1, nb_pos);
|
|
cio_write(d2pfp(val), nb_sv);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
printf("errore\n");
|
|
}
|
|
|
|
break;
|
|
case 5:
|
|
//MAXERR
|
|
printf("Opzione MAXERR non supportata\n");
|
|
break;
|
|
default:
|
|
printf("opzione riservata per uso futuro\n");
|
|
}
|
|
for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
|
|
free(PSNR[i]);
|
|
free(PSNR);
|
|
for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
|
|
free(dPSNR[i]);
|
|
free(dPSNR);
|
|
for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
|
|
free(dMSE[i]);
|
|
free(dMSE);
|
|
|
|
len = cio_tell() - set;
|
|
cio_seek(set);
|
|
cio_write(len, 2);
|
|
cio_skip(len - 2);
|
|
}
|
|
|
|
|
|
int JPWL_len_EPB(unsigned int LDPepb, unsigned int Pepb, unsigned char Depb){
|
|
unsigned int len = 11, n1, n2, k1, k2, lenp;
|
|
char pos_epb;
|
|
|
|
|
|
lenp = cio_tell();
|
|
/* determino len_epb e i parametri di codifica*/
|
|
pos_epb= Depb & 0x3F;
|
|
if ((j2k_state == J2K_STATE_MH) && !(pos_epb)){ // sto scrivendo il primo epb del mh
|
|
n1=160;
|
|
k1=64;
|
|
len += (n1 - k1)*(unsigned int)ceil((double)(lenp + 11)/k1);
|
|
} else {if ((j2k_state == J2K_STATE_TPH) && !(pos_epb)){ // primo epb di un tph
|
|
n1=80;
|
|
k1=25;
|
|
len += 55;
|
|
} else { // altro epb
|
|
n1=40;
|
|
k1=13;
|
|
len += 27;
|
|
}
|
|
}
|
|
if (!Pepb) { // per codificare i dati seguenti uso lo stesso codice di prima
|
|
n2 = n1;
|
|
k2 = k1;
|
|
len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
|
|
|
|
} else{
|
|
if (Pepb == 0xffffffff)
|
|
1;
|
|
|
|
else {if ((Pepb >> 28)== 1){
|
|
if ((Pepb & 0x00000001)){
|
|
len += 4;
|
|
} else {
|
|
len +=2;
|
|
}
|
|
} else {if ((Pepb >> 28)== 2){
|
|
n2 = ((Pepb & 0x0000ff00)>> 8);
|
|
k2 = (Pepb & 0x000000ff);
|
|
len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
void jpwl_write_RED(){
|
|
//questa funzione scrive un marker RED di test vuoto
|
|
cio_write(JPWL_MS_RED,2);
|
|
//già scrivo la len(non metto informazioni nel marker, poichè la codestream sarà corretta)
|
|
cio_write(3,2);
|
|
cio_write(jpwl_cp.pred,1);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void JPWL_write_Pepbs(long *pepbs, int num_epb){
|
|
int i, lenp, pos;
|
|
|
|
cio_write(0,2); // id relativo all'uso degli epb
|
|
cio_skip(2);
|
|
lenp=cio_tell();
|
|
/*
|
|
Qui in base a come deciderò di far operare l'encoder dovrò trovare il modo di inserire
|
|
i Pepb relativi alla struttura; In questo caso uso una struttura fissa che prevede un
|
|
solo epb nel main header che usa lo stesso codice relativo al primo epb e più epb per
|
|
ogni tile part header, il primo che protegge tutto il tph con lo stesso codice relativo
|
|
al primo epb del tile part, gli altri a protezione dei dati con un codice rs specificato
|
|
*/
|
|
for (i=0; i<num_epb; i++)
|
|
cio_write(pepbs[i],4);
|
|
// scrivo la Lid
|
|
pos=cio_tell();
|
|
cio_seek(lenp-2);
|
|
cio_write(pos-lenp,2);
|
|
cio_seek(pos);
|
|
}
|
|
|
|
void correggi_esd(int offset, int len_esd, int Pesd){
|
|
//nel caso in cui i dati dell'esd sono posti in byte range mode, devo correggere con l'offset
|
|
//pari alla somma della lunghezza del primo epb e dell'epc
|
|
int nb_pos, nb_sv, start, end, set, p;
|
|
p=cio_tell();
|
|
//mi metto all'inizio dei dati dell'esd
|
|
cio_skip(6);
|
|
//printf("marker: %x\n", cio_read(2));
|
|
//printf("len: %x\n", cio_read(2));
|
|
//printf("info: %x\n", cio_read(2));
|
|
//determino i parametri con cui sono scritti i dati
|
|
nb_pos = (((Pesd & 0x02)>>1)==0) ? 2 : 4;
|
|
nb_sv = (((Pesd & 0x04)>>2)==0) ? 1 : 2;
|
|
//printf("offset: %x\n",offset);
|
|
//printf("len_esd: %d\n", len_esd);
|
|
//procedo alla correzione
|
|
while ((cio_tell()-p)<len_esd) {
|
|
set=cio_tell();
|
|
start = cio_read(nb_pos);
|
|
//printf("start: %d\n", start);
|
|
end = cio_read(nb_pos);
|
|
//printf("end: %d\n", end);
|
|
cio_seek(set);
|
|
cio_write(start + offset, nb_pos);
|
|
cio_write(end + offset, nb_pos);
|
|
cio_skip(nb_sv);
|
|
//printf("pos: %d\n", cio_tell());
|
|
}
|
|
|
|
}
|
|
|
|
int pianifica_epb(unsigned int LDPepb, unsigned int Pepb, int *n_epb ){
|
|
int len_max, *num_epb, n2, k2;
|
|
//serve per pianificare il numero di epb necessari per proteggere i dati
|
|
num_epb = n_epb;
|
|
if ((Pepb >> 28)== 2){
|
|
n2 = ((Pepb & 0x0000ff00)>> 8);
|
|
k2 = (Pepb & 0x000000ff);
|
|
len_max = 0xFF80 * k2 / (n2 - k2);
|
|
*num_epb = (int) ceil((double) LDPepb / len_max);
|
|
} else if (!Pepb){
|
|
n2 = 40;
|
|
k2 = 13;
|
|
len_max = 0xFF80 * k2 / (n2 - k2);
|
|
*num_epb = (int) ceil((double) LDPepb / len_max);
|
|
} else {
|
|
*num_epb = 1;
|
|
len_max = LDPepb+2;
|
|
}
|
|
return len_max;
|
|
}
|
|
|
|
|
|
|
|
int uep(int notil, char *bs, char *header, int len_header){
|
|
//questa funzione ritorna il valore di psot_corr
|
|
double maxMSE, val, dMSE, M;
|
|
int depb, mask, corr=0, len_til, npix, lung=0, i, h=0, k, l=0, npack, start[6], end[6], fa=0, pkt=0, Psot_cor=0, lmax[6], no_epb[6], len[6], set, cont, tot_epb=0;
|
|
char *data;
|
|
double *PSNR;
|
|
|
|
PSNR = (double *) malloc(info_IM.num*sizeof(double));
|
|
//printf("uep\n");
|
|
|
|
//mi piazzo alla fine di SOT
|
|
set=cio_tell();
|
|
|
|
//determino il psnr che si raggiunge con ogni pacchetto
|
|
M = 65025;
|
|
//printf("M: %f\n",M);
|
|
val = 0;
|
|
npix = info_IM.tile[notil-1].nbpix;
|
|
maxMSE = info_IM.tile[notil-1].distotile / npix;
|
|
//printf("max mse:%f\n", maxMSE);
|
|
for(npack=0; npack < (info_IM.num); npack++){
|
|
dMSE = info_IM.tile[notil-1].packet[npack].disto / npix;
|
|
//printf("dmse: %f\n", dMSE);
|
|
if (dMSE!=0){
|
|
val += dMSE;
|
|
PSNR[npack] = (10 * log10(M/(maxMSE - val)));
|
|
}
|
|
else {
|
|
PSNR[npack] = PSNR[npack-1];
|
|
}
|
|
printf("psnr %d: %f\n ", npack, PSNR[npack] );
|
|
}
|
|
|
|
//a questo punto determino le fasce
|
|
npack=0;
|
|
|
|
//inizializzo le posizioni
|
|
for (i=0;i<6;i++){
|
|
start[i]=-1;
|
|
end[i]=-1;
|
|
}
|
|
start[0]=0;
|
|
while (npack<info_IM.num){
|
|
//printf("conta: %d\n", npack);
|
|
if (PSNR[npack]<20){
|
|
npack++;
|
|
}
|
|
else if ((PSNR[npack]>=20)&&(PSNR[npack]<23)){
|
|
if (fa!=1){
|
|
fa=1;
|
|
end[0]=npack++;
|
|
start[1]=npack;
|
|
}
|
|
else
|
|
npack++;
|
|
|
|
}
|
|
else if ((PSNR[npack]>=23)&&(PSNR[npack]<26)){
|
|
if (fa!=2){
|
|
end[fa]=npack++;
|
|
start[2]=npack;
|
|
fa=2;
|
|
}
|
|
else
|
|
npack++;
|
|
|
|
}
|
|
else if ((PSNR[npack]>=26)&&(PSNR[npack]<35)){
|
|
if (fa!=3){
|
|
end[fa]=npack++;
|
|
start[3]=npack;
|
|
fa=3;
|
|
}
|
|
else
|
|
npack++;
|
|
|
|
}
|
|
else if ((PSNR[npack]>=35)&&(PSNR[npack]<37)){
|
|
if (fa!=4){
|
|
end[fa]=npack++;
|
|
start[4]=npack;
|
|
fa=4;
|
|
}
|
|
else
|
|
npack++;
|
|
|
|
}
|
|
else{
|
|
end[fa]=info_IM.num-1;
|
|
npack=info_IM.num;
|
|
fa=5;
|
|
|
|
}
|
|
|
|
}
|
|
// devo mettere la fine all'ultima fascia abilitata
|
|
if (fa!=5){
|
|
//risolvo un bug!!
|
|
if(start[fa] == info_IM.num){
|
|
//disattivo l'ultima fascia se non correttamente abilitata
|
|
start[fa] = -1;
|
|
fa--;
|
|
}
|
|
else
|
|
end[fa]=info_IM.num-1;
|
|
}
|
|
printf("livello start end\n");
|
|
for (i=0;i<6;i++)
|
|
printf("%d\t%d\t%d\n", i, start[i], end[i]);
|
|
|
|
for (i=0;i<6;i++)
|
|
printf("pepb[%d]: %x\n", i, jpwl_cp.pepb[i]);
|
|
|
|
//determino anticipatamente le lunghezze degli epb
|
|
if (len_header)
|
|
Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2;
|
|
fa=0;
|
|
//devo calcolare le lunghezze degli epb necessari per ogni fascia
|
|
for(i=0;i<5;i++){
|
|
len[i]=0;
|
|
if ((start[i]!=-1)&&(end[i]!=-1)){
|
|
len[i]= (info_IM.tile[notil-1].packet[end[i]].end_pos) - info_IM.tile[notil-1].packet[start[i]].start_pos +1;
|
|
/*printf("len[%d]: %d\n",i, len[i]); */
|
|
if (i==0)
|
|
//poichè non viene considerato il marker SOD
|
|
len[i]+=2;
|
|
lmax[i] = pianifica_epb(len[i], jpwl_cp.pepb[i+1], &no_epb[i]);
|
|
/*printf("lmax[%d]: %d\n", i, lmax[i]);*/
|
|
tot_epb+=no_epb[i];
|
|
/*printf("num epb[%d]: %d\n",i, no_epb[i]);*/
|
|
if(no_epb[i] > 1){
|
|
if ((!(len_header))&&(i==1))
|
|
Psot_cor += JPWL_len_EPB(lmax[i], jpwl_cp.pepb[i+1], 0) + (no_epb[i]-2)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
|
|
else
|
|
Psot_cor += (no_epb[i]-1)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
|
|
}
|
|
else{
|
|
if ((!(len_header))&&(i==1))
|
|
Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0);
|
|
else
|
|
Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41);
|
|
}
|
|
|
|
Psot_cor += 2*(no_epb[i]);
|
|
fa=i;
|
|
|
|
|
|
}
|
|
}
|
|
/*printf("fa: %d\n", fa);
|
|
printf("psot_cor: %d\n", Psot_cor);
|
|
printf("tot_epb: %d\n", tot_epb);*/
|
|
/*len[5]=0;
|
|
for(i=0;i<5;i++){
|
|
len[5]+=len[i];
|
|
}*/
|
|
/*printf("lendata: %d\n", len[5]);*/
|
|
cio_seek(set - 6);
|
|
len_til=cio_read(4);
|
|
cio_skip(-4);
|
|
cio_write(Psot_cor + len_til,4);
|
|
|
|
cio_seek(set);
|
|
//correzione index
|
|
if (info_IM.index_on){
|
|
corr += Psot_cor;
|
|
info_IM.tile[notil-1].end_header += corr;
|
|
info_IM.tile[notil-1].end_pos += corr;
|
|
if (notil < j2k_cp->tw * j2k_cp->th)
|
|
info_IM.tile[notil].start_pos += corr;
|
|
pack_corr(corr, notil-1);
|
|
}
|
|
//scrivo gli EPB e riporto i buffer
|
|
if (len_header){
|
|
JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0);
|
|
h=1;
|
|
pepbs[cont_epb++]=jpwl_cp.pepb[0];
|
|
}
|
|
for (i = 0; i < len_header; i++)
|
|
cio_write(header[i],1);
|
|
free(header);
|
|
mask = (tot_epb == 1) ? 0x40 : 0x80;
|
|
for(i=0;i<5;i++){
|
|
if ((start[i]!=-1)&&(end[i]!=-1)){
|
|
data = (unsigned char *)malloc(lmax[i]*sizeof(unsigned char));
|
|
for (k=0; k < no_epb[i]; k++){
|
|
cont=0;
|
|
depb = mask | ((l+h)&0x3F);
|
|
|
|
while (((cont + k*lmax[i])< len[i])&&(cont < lmax[i])){
|
|
data[cont] = bs[cont + k*lmax[i] + lung];
|
|
cont++;
|
|
}
|
|
if ((cont < lmax[i])&&(i==fa))
|
|
depb |= 0x40;
|
|
/*printf("depb[%d]: %x\n",i, depb);*/
|
|
JPWL_write_EPB(data, cont, jpwl_cp.pepb[i+1], depb);
|
|
pepbs[cont_epb++]=jpwl_cp.pepb[i+1];
|
|
if (l==1)
|
|
scavalcato=1;
|
|
l++;
|
|
}
|
|
free(data);
|
|
lung+=len[i];
|
|
}
|
|
}
|
|
|
|
/*printf("lung: %d\n", lung );*/
|
|
return Psot_cor;
|
|
|
|
}
|
|
|
|
|
|
|
|
int uep_lay(int notil, char *bs, char *header, int len_header){
|
|
//questa funzione ritorna il valore di psot_corr
|
|
int depb, mask, corr=0, len_til, n_lay, lung=0, i, h=0, k, l=0, npack, Psot_cor=0, set, cont, tot_epb=0;
|
|
char *data;
|
|
int *lmax, *no_epb, *len;
|
|
|
|
//determino il numero dei layer
|
|
n_lay = info_IM.Layer;
|
|
|
|
//determino il numero di pacchetti per layer
|
|
npack = info_IM.num / n_lay;
|
|
|
|
//preparo i vettori necessari
|
|
|
|
if(!(lmax=(int *) malloc(n_lay * sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma3\n ");
|
|
if(!(no_epb=(int *) malloc(n_lay * sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma3\n ");
|
|
if(!(len=(int *) malloc(n_lay * sizeof(int))))
|
|
printf("Non può essere allocata memoria per eseguire il programma3\n ");
|
|
|
|
//mi piazzo alla fine di SOT
|
|
set=cio_tell();
|
|
|
|
|
|
//determino anticipatamente le lunghezze degli epb
|
|
if (len_header)
|
|
Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2;
|
|
|
|
//devo calcolare le lunghezze degli epb necessari per ogni fascia
|
|
for(i=0;i<n_lay;i++){
|
|
//determino le lunghezze dei layer
|
|
len[i] = (info_IM.tile[notil-1].packet[((i+1) * npack) - 1].end_pos) - info_IM.tile[notil-1].packet[i * npack].start_pos +1;
|
|
/*printf("len[%d]: %d\n",i, len[i]); */
|
|
if (i==0)
|
|
//poichè non viene considerato il marker SOD
|
|
len[i]+=2;
|
|
lmax[i] = pianifica_epb(len[i], jpwl_cp.pepb[i+1], &no_epb[i]);
|
|
/*printf("lmax[%d]: %d\n", i, lmax[i]);*/
|
|
tot_epb+=no_epb[i];
|
|
/*printf("num epb[%d]: %d\n",i, no_epb[i]);*/
|
|
if(no_epb[i] > 1){
|
|
if ((!(len_header))&&(i==1))
|
|
Psot_cor += JPWL_len_EPB(lmax[i], jpwl_cp.pepb[i+1], 0) + (no_epb[i]-2)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
|
|
else
|
|
Psot_cor += (no_epb[i]-1)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
|
|
}
|
|
else{
|
|
if ((!(len_header))&&(i==1))
|
|
Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0);
|
|
else
|
|
Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41);
|
|
}
|
|
|
|
Psot_cor += 2*(no_epb[i]);
|
|
}
|
|
|
|
//correzione di psot
|
|
cio_seek(set - 6);
|
|
len_til=cio_read(4);
|
|
cio_skip(-4);
|
|
cio_write(Psot_cor + len_til,4);
|
|
cio_seek(set);
|
|
|
|
//correzione index
|
|
if (info_IM.index_on){
|
|
corr += Psot_cor;
|
|
info_IM.tile[notil-1].end_header += corr;
|
|
info_IM.tile[notil-1].end_pos += corr;
|
|
if (notil < j2k_cp->tw * j2k_cp->th)
|
|
info_IM.tile[notil].start_pos += corr;
|
|
pack_corr(corr, notil-1);
|
|
}
|
|
|
|
//scrivo gli EPB e riporto i buffer
|
|
if (len_header){
|
|
JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0);
|
|
h=1;
|
|
pepbs[cont_epb++]=jpwl_cp.pepb[0];
|
|
}
|
|
for (i = 0; i < len_header; i++)
|
|
cio_write(header[i],1);
|
|
free(header);
|
|
|
|
//EPB a protezione della bitstream
|
|
mask = (tot_epb == 1) ? 0x40 : 0x80;
|
|
for(i=0;i<n_lay;i++){
|
|
//preparo il buffer con i dati da proteggere
|
|
data = (unsigned char *)malloc(lmax[i]*sizeof(unsigned char));
|
|
for (k=0; k < no_epb[i]; k++){
|
|
cont=0;
|
|
depb = mask | ((l+h)&0x3F);
|
|
|
|
while (((cont + k*lmax[i])< len[i])&&(cont < lmax[i])){
|
|
data[cont] = bs[cont + k*lmax[i] + lung];
|
|
cont++;
|
|
}
|
|
if ((cont < lmax[i]) && (i == (n_lay-1)))
|
|
depb |= 0x40;
|
|
/*printf("depb[%d]: %x\n",i, depb);*/
|
|
JPWL_write_EPB(data, cont, jpwl_cp.pepb[i+1], depb);
|
|
pepbs[cont_epb++]=jpwl_cp.pepb[i+1];
|
|
if (l==1)
|
|
scavalcato=1;
|
|
l++;
|
|
}
|
|
free(data);
|
|
lung+=len[i];
|
|
|
|
}
|
|
free(len);
|
|
free(no_epb);
|
|
free(lmax);
|
|
/*printf("lung: %d\n", lung );*/
|
|
return Psot_cor;
|
|
|
|
}
|
|
|
|
|
|
int jpwl_encode(char *input, char * output, unsigned long CL){
|
|
long len_tot, len_primo_epb, len_til, Psot_cor;
|
|
unsigned char *buf1, *buf2, *buf3, *data;
|
|
int h=0,pos, end_siz, i, depb, len_SIZ, notil, len_mar, len_red, mark, set, end_tph, len_data1, len_data2, len_data3, cur_pos, fine_mh, len_epc, corr=0, len_esd=0, lmax, no_epb, cont, mask;
|
|
|
|
|
|
// controllo se devo usare gli epb
|
|
if (jpwl_cp.EPB_on){
|
|
|
|
//parser, serve a determinare le lunghezze degli epb e scrivere quelli nei tile part
|
|
cio_init(input, CL*4);
|
|
len_tot=CL;
|
|
cio_skip(4);
|
|
len_mar = cio_read(2);
|
|
cio_skip(len_mar-2);
|
|
end_siz=cio_tell();
|
|
j2k_state = J2K_STATE_MH;
|
|
mark = cio_read(2);
|
|
//printf("mark: %x\n",mark);
|
|
while (mark!=0xff90){
|
|
len_mar = cio_read(2);
|
|
cio_skip(len_mar-2);
|
|
mark = cio_read(2);
|
|
//printf("mark: %x\n",mark);
|
|
}
|
|
fine_mh=cio_tell()-2;
|
|
cont_epb=1;
|
|
pepbs[0]=jpwl_cp.pepb[0];
|
|
|
|
j2k_state = J2K_STATE_TPH;
|
|
for (notil=1; notil <= j2k_cp->tw * j2k_cp->th; notil++){
|
|
Psot_cor = 0;
|
|
//trucco per non fare sbagliare nella scrittura di più di 64 epb
|
|
scavalcato=0;
|
|
cio_skip(4);
|
|
len_til = cio_read(4);
|
|
cio_skip(2);
|
|
set = cio_tell();
|
|
mark = cio_read(2);
|
|
//printf("mark: %x\n",mark);
|
|
while (mark!=0xff93){
|
|
len_mar = cio_read(2);
|
|
cio_skip(len_mar-2);
|
|
mark = cio_read(2);
|
|
//printf("mark: %x\n",mark);
|
|
}
|
|
end_tph = cio_tell()-2;
|
|
len_data1= end_tph - set;
|
|
len_data2= len_til+set-end_tph-12;
|
|
/*printf("lendata2: %d\n",len_data2);*/
|
|
buf1 = (unsigned char *) malloc(len_data1*sizeof(unsigned char));
|
|
buf2 = (unsigned char *) malloc(len_data2*sizeof(unsigned char));
|
|
cio_seek(set);
|
|
for (i=0; i<len_data1; i++)
|
|
buf1[i]=cio_read(1);
|
|
for (i=0; i<len_data2; i++)
|
|
buf2[i]=cio_read(1);
|
|
cur_pos=cio_tell();
|
|
len_data3 = len_tot-cur_pos;
|
|
buf3 = (unsigned char *) malloc((len_data3)*sizeof(unsigned char));
|
|
for (i=0; i< len_data3; i++)
|
|
buf3[i]=cio_read(1);
|
|
//uep
|
|
if (jpwl_cp.UEP_on){
|
|
cio_seek(set);
|
|
Psot_cor=uep_lay(notil,buf2,buf1,len_data1);
|
|
//free(buf1);
|
|
len_tot += Psot_cor;
|
|
}
|
|
else{
|
|
//correzione Psot
|
|
if (len_data1)
|
|
Psot_cor += JPWL_len_EPB((len_data1), jpwl_cp.pepb[0], 0) + 2;
|
|
lmax = pianifica_epb(len_data2, jpwl_cp.pepb[1], &no_epb);
|
|
//printf("num epb: %d\n", no_epb);
|
|
if(no_epb > 1){
|
|
if (len_data1)
|
|
Psot_cor += (no_epb-1)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41);
|
|
else
|
|
Psot_cor += JPWL_len_EPB(lmax, jpwl_cp.pepb[1], 0) + (no_epb-2)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41);
|
|
}
|
|
else{
|
|
if (len_data1)
|
|
Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x41);
|
|
else
|
|
Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x0);
|
|
}
|
|
Psot_cor += 2*(no_epb);
|
|
len_tot += Psot_cor;
|
|
//Psot_cor += len_til;
|
|
cio_seek(set - 6);
|
|
cio_write(Psot_cor + len_til,4);
|
|
|
|
cio_seek(set);
|
|
//correzione index
|
|
if (info_IM.index_on){
|
|
corr += Psot_cor;
|
|
info_IM.tile[notil-1].end_header += corr;
|
|
info_IM.tile[notil-1].end_pos += corr;
|
|
if (notil < j2k_cp->tw * j2k_cp->th)
|
|
info_IM.tile[notil].start_pos += corr;
|
|
pack_corr(corr, notil-1);
|
|
}
|
|
//scrivo gli EPB e riporto i buffer
|
|
if (len_data1){
|
|
JPWL_write_EPB(buf1, len_data1, jpwl_cp.pepb[0], 0);
|
|
h=1;
|
|
pepbs[cont_epb++]=jpwl_cp.pepb[0];
|
|
}
|
|
for (i = 0; i < len_data1; i++)
|
|
cio_write(buf1[i],1);
|
|
free(buf1);
|
|
mask = (no_epb == 1) ? 0x40 : 0x80;
|
|
data = (unsigned char *)malloc(lmax*sizeof(unsigned char));
|
|
for (i=0; i < no_epb; i++){
|
|
cont=0;
|
|
depb = mask | ((i+h)&0x3F);
|
|
while (((cont + i*lmax)< len_data2)&&(cont < lmax)){
|
|
data[cont] = buf2[cont + i*lmax];
|
|
cont++;
|
|
}
|
|
if (cont < lmax)
|
|
depb |= 0x40;
|
|
JPWL_write_EPB(data, cont, jpwl_cp.pepb[1], depb);
|
|
pepbs[cont_epb++]=jpwl_cp.pepb[1];
|
|
if (i==1)
|
|
scavalcato=1;
|
|
}
|
|
free(data);
|
|
}
|
|
for (i = 0; i < len_data2; i++)
|
|
cio_write(buf2[i],1);
|
|
cur_pos=cio_tell();
|
|
free(buf2);
|
|
for (i=0; i < len_data3; i++)
|
|
cio_write(buf3[i],1);
|
|
free(buf3);
|
|
cio_seek(cur_pos);
|
|
mark = cio_read(2);
|
|
|
|
}
|
|
|
|
//ora mi trovo alla fine della codestream
|
|
len_tot=cio_tell();
|
|
// controllo se devo inserire l'esd (non lo devo inserire qui se è attivo il packet range mode)
|
|
if ((jpwl_cp.ESD_on)&(!(((jpwl_cp.pesd & 0xC0)>>6)==2))){
|
|
cio_seek(end_siz);
|
|
len_data1 = len_tot - end_siz;
|
|
buf1 = (unsigned char *) malloc(len_data1 * sizeof(unsigned char));
|
|
for (i = 0; i < len_data1; i++){
|
|
buf1[i] = cio_read(1);
|
|
}
|
|
//printf("%x%x\n", buf1[len_tot - set - 2], buf1[len_tot - set -1]);
|
|
cio_seek(end_siz);
|
|
jpwl_write_ESD(jpwl_cp.pesd, 0);
|
|
len_esd = cio_tell() - end_siz;
|
|
//printf("len esd: %d\n",len_esd);
|
|
len_tot += len_esd;
|
|
for (i = 0; i < len_data1; i++){
|
|
cio_write(buf1[i],1);
|
|
}
|
|
free(buf1);
|
|
}
|
|
|
|
//scrivo l'epc ed il primo epb
|
|
cio_init(output, len_tot*2);
|
|
j2k_state = J2K_STATE_MH;
|
|
for (i=0; i< 6; i++){
|
|
output[i]=input[i];
|
|
}
|
|
cio_skip(4);
|
|
len_SIZ = cio_read(2);
|
|
for (i=6; i< 4+len_SIZ; i++){
|
|
output[i]=input[i];
|
|
}
|
|
cio_skip(len_SIZ-2);
|
|
set = cio_tell();
|
|
len_epc = 15 + cont_epb*4;
|
|
len_primo_epb=JPWL_len_EPB(fine_mh - set + len_epc, jpwl_cp.pepb[0], 0);
|
|
len_red=(jpwl_cp.RED_on)? 5 : 0;
|
|
if (info_IM.index_on){
|
|
corr=len_epc + len_primo_epb + 2 + len_esd + len_red;
|
|
info_IM.Main_head_end += corr;
|
|
//printf("fine_mh: %d\n",info_IM.Main_head_end);
|
|
//printf("%d\n", info_IM.tile[0].start_pos);
|
|
info_IM.tile[0].start_pos += corr;
|
|
for (i=0; i < j2k_cp->th * j2k_cp->tw; i++){
|
|
info_IM.tile[i].end_header += corr;
|
|
info_IM.tile[i].end_pos += corr;
|
|
if (i < j2k_cp->tw * j2k_cp->th)
|
|
info_IM.tile[i+1].start_pos += corr;
|
|
pack_corr(corr, i);
|
|
}
|
|
}
|
|
|
|
jpwl_write_EPC_fin(len_tot+len_primo_epb+2+len_esd+len_red, pepbs, cont_epb);
|
|
//controllo se devo inserire la red (solo test)
|
|
if (jpwl_cp.RED_on)
|
|
jpwl_write_RED();
|
|
pos=cio_tell();
|
|
//scrivo da input il main header
|
|
for (i=4+len_SIZ; i<fine_mh+len_esd; i++){
|
|
cio_write(input[i],1);
|
|
}
|
|
cur_pos = cio_tell();
|
|
//se l'esd è presente ed è in byte range mode devo correggere la posizioni
|
|
if (jpwl_cp.ESD_on && (((jpwl_cp.pesd & 0xC0)>>6)==1) ){
|
|
cio_seek(pos);
|
|
correggi_esd(corr, len_esd, jpwl_cp.pesd);
|
|
}
|
|
|
|
len_data1=cur_pos-set;
|
|
buf1= (unsigned char *) malloc((len_data1)*sizeof(unsigned char));
|
|
cio_seek(set);
|
|
for (i=0; i< len_data1; i++){
|
|
buf1[i]=cio_read(1);
|
|
}
|
|
cio_seek(set);
|
|
JPWL_write_EPB(buf1, len_data1, jpwl_cp.pepb[0], 0x40);
|
|
for (i = 0; i < len_data1; i++)
|
|
cio_write(buf1[i],1);
|
|
free(buf1);
|
|
for (i = fine_mh+len_esd; i < len_tot; i++)
|
|
cio_write(input[i],1);
|
|
|
|
|
|
}
|
|
|
|
|
|
// se devo inserire l'epc da solo lo posiziono subito dopo SIZ
|
|
else {
|
|
len_esd=0;
|
|
cio_init(output, CL*2);
|
|
for (i=0; i< 6; i++){
|
|
output[i]=input[i];
|
|
}
|
|
cio_skip(4);
|
|
len_SIZ = cio_read(2);
|
|
for (i=6; i< 4+len_SIZ; i++){
|
|
output[i]=input[i];
|
|
}
|
|
cio_skip(len_SIZ-2);
|
|
set = cio_tell();
|
|
// controllo se devo inserire l'esd
|
|
if ((jpwl_cp.ESD_on)&(!(((jpwl_cp.pesd & 0xC0)>>6)==2))){
|
|
jpwl_write_ESD(jpwl_cp.pesd, 0);
|
|
len_esd = cio_tell() - set;
|
|
cio_seek(set);
|
|
buf1 = (unsigned char *) malloc(len_esd * sizeof(unsigned char));
|
|
for (i = 0; i < len_esd; i++){
|
|
buf1[i] = cio_read(1);
|
|
}
|
|
cio_seek(set);
|
|
len_red=(jpwl_cp.RED_on)? 5 : 0;
|
|
corr=len_esd+11+len_red;
|
|
//correzione delle posizioni dei pack nella struttura info image da fare nel caso di esd nel main header
|
|
if (info_IM.index_on){
|
|
info_IM.Main_head_end += corr;
|
|
//printf("fine_mh: %d\n",info_IM.Main_head_end);
|
|
info_IM.tile[0].start_pos += corr;
|
|
for (i=0; i < j2k_cp->th * j2k_cp->tw; i++){
|
|
info_IM.tile[i].end_header += corr;
|
|
info_IM.tile[i].end_pos += corr;
|
|
if (i < j2k_cp->tw * j2k_cp->th)
|
|
info_IM.tile[i+1].start_pos += corr;
|
|
pack_corr(corr, i);
|
|
}
|
|
}
|
|
}
|
|
jpwl_write_EPC_fin(CL + len_esd, NULL, 0);
|
|
//controllo se devo inserire la red (solo test)
|
|
if (jpwl_cp.RED_on)
|
|
jpwl_write_RED();
|
|
set=cio_tell();
|
|
if (jpwl_cp.ESD_on){
|
|
for (i = 0; i < len_esd; i++){
|
|
cio_write(buf1[i],1);
|
|
}
|
|
free(buf1);
|
|
if (((jpwl_cp.pesd & 0xC0)>>6)==1) {
|
|
cio_seek(set);
|
|
correggi_esd(corr, len_esd, jpwl_cp.pesd);
|
|
}
|
|
}
|
|
for (i=4+len_SIZ; i < CL; i++){
|
|
cio_write(input[i],1);
|
|
}
|
|
}
|
|
|
|
|
|
return cio_tell();
|
|
|
|
}
|
|
|
|
void get_jpwl_cp(j2k_cp_t *cp){
|
|
char risp, scelta,choose;
|
|
int out = 0;
|
|
unsigned long n;
|
|
j2k_cp_t *param;
|
|
|
|
param = cp;
|
|
printf("You have chosen to activate JPWL techniques. EPC will be inserted\n");
|
|
if (param->intermed_file){
|
|
printf("Since intermed file option is active, EPC will not contain any information on the");
|
|
printf("codestream length: eventual ESDs will be written in tile part headers.\n\n\n");
|
|
}
|
|
printf("Do you want to use EPBs (y/n)?: ");
|
|
risp = (char) _getche();
|
|
printf("\n\n\n");
|
|
do {
|
|
switch (risp){
|
|
case 'y':
|
|
jpwl_cp.EPB_on = 1;
|
|
do{
|
|
printf("UEP or EEP (u,e)?: ");
|
|
choose = (char) _getche();
|
|
printf("\n\n\n");
|
|
}while(!strchr("ue",choose));
|
|
if (choose=='e'){
|
|
do{
|
|
printf("Header protecting EPBs settings\n");
|
|
printf("1) Adopt the same RS code used for the EPB;\n");
|
|
printf("2) Enter a RS(n,32) code;\n");
|
|
printf("3) Use CRC-16(CCITT);\n");
|
|
printf("4) Use CRC-32(ETHERNET);\n");
|
|
printf("5) No protection at all.\n\n\n");
|
|
scelta = (char) _getche();
|
|
printf("\n\n");
|
|
}while(!strchr("12345",scelta));
|
|
if (scelta == '1')
|
|
jpwl_cp.pepb[0]=0x00000000;
|
|
if (scelta == '2'){
|
|
do {
|
|
printf("Enter the desired n value (k=32 as standard; n between 37 and 128): ");
|
|
scanf("%d", &n);
|
|
printf("\n\n\n");
|
|
} while ((n<37)||(n>128));
|
|
jpwl_cp.pepb[0] = ( n & 0x000000FF)<<8;
|
|
jpwl_cp.pepb[0] |= 0x20000020;
|
|
}
|
|
if (scelta == '3')
|
|
jpwl_cp.pepb[0] = 0x10000000;
|
|
if (scelta == '4')
|
|
jpwl_cp.pepb[0] = 0x10000001;
|
|
if (scelta == '5')
|
|
jpwl_cp.pepb[0] = 0xFFFFFFFF;
|
|
printf("pepb1: %x\n", jpwl_cp.pepb[0]);
|
|
do{
|
|
printf("Data protecting EPBs settings\n");
|
|
printf("1) Adopt the same RS code used for the EPB;\n");
|
|
printf("2) Enter a RS(n,32) code;\n");
|
|
printf("3) Use CRC-16(CCITT);\n");
|
|
printf("4) Use CRC-32(ETHERNET);\n");
|
|
printf("5) No protection at all.\n\n\n");
|
|
scelta = (char) _getche();
|
|
printf("\n\n");
|
|
}while(!strchr("12345",scelta));
|
|
if (scelta == '1')
|
|
jpwl_cp.pepb[1]=0x00000000;
|
|
if (scelta == '2'){
|
|
do {
|
|
printf("Enter the desired n value (k=32 as standard; n between 37 and 128): ");
|
|
scanf("%d", &n);
|
|
printf("\n\n\n");
|
|
} while ((n<37)||(n>128));
|
|
jpwl_cp.pepb[1] = ( n & 0x000000FF)<<8;
|
|
jpwl_cp.pepb[1] |= 0x20000020;
|
|
}
|
|
if (scelta == '3')
|
|
jpwl_cp.pepb[1] = 0x10000000;
|
|
if (scelta == '4')
|
|
jpwl_cp.pepb[1] = 0x10000001;
|
|
if (scelta == '5')
|
|
jpwl_cp.pepb[1] = 0xFFFFFFFF;
|
|
printf("pepb2: %x\n", jpwl_cp.pepb[1]);
|
|
out=1;
|
|
}
|
|
if (choose=='u'){
|
|
printf("N.B.: layer number must be less than or equal to five\n");
|
|
param->index_on = 1;
|
|
jpwl_cp.UEP_on = 1;
|
|
jpwl_cp.pepb[0] = 0x20008020;
|
|
jpwl_cp.pepb[1] = 0x20005520;
|
|
jpwl_cp.pepb[2] = 0x20004B20;
|
|
jpwl_cp.pepb[3] = 0x20002520;
|
|
jpwl_cp.pepb[4] = 0x20002520;
|
|
jpwl_cp.pepb[5] = 0x20002520;
|
|
out=1;
|
|
}
|
|
|
|
break;
|
|
case 'n':
|
|
out=1;
|
|
break;
|
|
default:
|
|
printf("Error in answer.\n");
|
|
printf("Do you want to use EPBs (y/n)?: ");
|
|
risp = (char) _getche();
|
|
printf("\n\n\n");
|
|
}
|
|
}while (!out);
|
|
out = 0;
|
|
printf("Do you want to use ESD (y/n)?: ");
|
|
risp = (char) _getche();
|
|
printf("\n\n\n");
|
|
do {
|
|
switch(risp){
|
|
case 'y':
|
|
jpwl_cp.ESD_on = 1;
|
|
param->index_on = 1;
|
|
jpwl_cp.pesd = 0x01;
|
|
do{
|
|
printf("Enter representation mode:\n");
|
|
printf("1) Packet mode;\n");
|
|
printf("2) Byte range mode;\n");
|
|
printf("3) Packet range mode.\n");
|
|
scelta = (char) _getche();
|
|
printf("\n\n");
|
|
}while(!strchr("123",scelta));
|
|
if (scelta =='1')
|
|
jpwl_cp.pesd |= 0x00;
|
|
if (scelta =='2')
|
|
jpwl_cp.pesd |= 0x42;
|
|
if (scelta =='3')
|
|
jpwl_cp.pesd |= 0x80;
|
|
do{
|
|
printf("Enter metrics:\n");
|
|
printf("1) Relative error sensitivity;\n");
|
|
printf("2) MSE;\n");
|
|
printf("3) MSE reduction;\n");
|
|
printf("4) PSNR;\n");
|
|
printf("5) PSNR increase.\n");
|
|
scelta = (char) _getche();
|
|
printf("\n\n");
|
|
}while(!strchr("12345",scelta));
|
|
if (scelta =='1')
|
|
jpwl_cp.pesd |= 0x00;
|
|
if (scelta =='2')
|
|
jpwl_cp.pesd |= 0x0C;
|
|
if (scelta =='3')
|
|
jpwl_cp.pesd |= 0x14;
|
|
if (scelta =='4')
|
|
jpwl_cp.pesd |= 0x1C;
|
|
if (scelta =='5')
|
|
jpwl_cp.pesd |= 0x24;
|
|
printf("pesd: %x\n", jpwl_cp.pesd);
|
|
out=1;
|
|
break;
|
|
case 'n':
|
|
out=1;
|
|
break;
|
|
default:
|
|
printf("Error entering the answer.\n");
|
|
printf("Do you want to use ESD (y/n)?: ");
|
|
risp = (char) _getche();
|
|
printf("\n\n\n");
|
|
}
|
|
}while (!out);
|
|
out = 0;
|
|
printf("Do you want to use RED (y/n)?: ");
|
|
risp = (char) _getche();
|
|
printf("\n\n\n");
|
|
do {
|
|
switch(risp){
|
|
case 'y':
|
|
jpwl_cp.RED_on = 1;
|
|
//suppongo che la codestream sia corretta => b0=0 e b5b4b3=000
|
|
jpwl_cp.pred = 0x00;
|
|
do{
|
|
printf("Enter representation mode:\n");
|
|
printf("1) Packet mode;\n");
|
|
printf("2) Byte range mode;\n");
|
|
printf("3) Packet range mode.\n");
|
|
scelta = (char) _getche();
|
|
printf("\n\n");
|
|
}while(!strchr("123",scelta));
|
|
if (scelta =='1')
|
|
jpwl_cp.pred |= 0x00;
|
|
if (scelta =='2')
|
|
jpwl_cp.pred |= 0x42;
|
|
if (scelta =='3')
|
|
jpwl_cp.pred |= 0x80;
|
|
printf("pred: %x\n", jpwl_cp.pred);
|
|
out=1;
|
|
break;
|
|
case 'n':
|
|
out=1;
|
|
break;
|
|
default:
|
|
printf("Error entering the answer.\n");
|
|
printf("Do you want to use RED (y/n)?: ");
|
|
risp = (char) _getche();
|
|
printf("\n\n\n");
|
|
}
|
|
}while (!out);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResetCRC()
|
|
{
|
|
crcSum = 0xffffffff;
|
|
}
|
|
|
|
|
|
void UpdateCRC16(char x)
|
|
{
|
|
int tmp;
|
|
tmp = ((x ^ (crcSum >> 8)) & 0xff);
|
|
crcSum = ((crcSum << 8) ^ CrcT16[tmp]) & 0xffff;
|
|
}
|
|
|
|
void UpdateCRC32(char x)
|
|
{
|
|
int tmp;
|
|
tmp = ((x ^ (crcSum >> 24)) & 0xff);
|
|
crcSum = ((crcSum << 8) ^ CrcT32[tmp]);
|
|
}
|
|
/* funzioni per l'inversione dei byte e del crc32 */
|
|
|
|
char reflectByte(char inbyte)
|
|
{
|
|
// reflect one byte
|
|
|
|
unsigned char outbyte=0;
|
|
unsigned char i=0x01;
|
|
unsigned char j;
|
|
|
|
for (j=0x080; j; j>>=1)
|
|
{
|
|
if (inbyte & i) outbyte|=j;
|
|
i<<=1;
|
|
}
|
|
|
|
return outbyte;
|
|
}
|
|
|
|
|
|
void reflectCRC32()
|
|
{
|
|
|
|
|
|
unsigned long outcrc=0;
|
|
unsigned long i=0x00000001;
|
|
unsigned long j;
|
|
|
|
for (j=0x80000000; j; j>>=1)
|
|
{
|
|
if (crcSum & i)
|
|
outcrc|=j;
|
|
i=i<<1;
|
|
}
|
|
crcSum = outcrc;
|
|
}
|
|
|
|
/*
|
|
int crc_ccitt(char *buffer, int len){
|
|
char c;
|
|
int i;
|
|
ResetCRC();
|
|
for (i=0; i<len; i++) {
|
|
c= *buffer;
|
|
UpdateCRC(c);
|
|
buffer++;
|
|
}
|
|
return crcSum;
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
//funzioni di conversione allo pseudo floating point format
|
|
short int d2pfp(double in){
|
|
long *punt, data;
|
|
short int mant, ex, out;
|
|
punt = ∈
|
|
punt++;
|
|
data = *punt;
|
|
mant = (data>>9) & 0x07FF;
|
|
ex = (data>>20) & 0x07FF;
|
|
out = ex+15;
|
|
out = out << 11;
|
|
out &= 0x0000F800;
|
|
out |= mant;
|
|
return out;
|
|
}
|
|
|
|
|
|
double pfp2d(short int in){
|
|
double out;
|
|
short int ex, mant;
|
|
mant = in & 0x07FF;
|
|
ex = (in >> 11) & 0x001F;
|
|
out = pow(2,ex-15)*(1+(mant/pow(2,11)));
|
|
return out;
|
|
}
|