// OPJFile.cc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "OPJFile.h"
#define MAX_LEVEL 20
OPJFile::OPJFile(char *filename)
: filename(filename)
{
version=0;
nr_spreads=0;
for(int i=0;i<MAX_SPREADS;i++) {
spreadname[i] = new char[25];
spreadname[i][0] = 0;
nr_cols[i] = 0;
maxrows[i] = 0;
for(int j=0;j<MAX_COLUMNS;j++) {
nr_rows[i][j] = 0;
colname[i][j] = new char[25];
colname[i][j][0] = 0x41+j;
colname[i][j][1] = 0;
coltype[i][j] = new char[25];
if(j==0)
coltype[i][j][0]='X';
else
coltype[i][j][0]='Y';
coltype[i][j][1]=0;
// for(int k=0;k<MAX_ROWS;k++) {
//sdata[i][j][k] = new char[25];
//sdata[i][j][k][0] = 0;
// }
}
}
}
/* File Structure :
filepre +
+ pre + head + data col A
+ pre + head + data col B
*/
/* parse file filename complete and save values */
int OPJFile::Parse() {
int i,j;
FILE *f, *debug;
if((f=fopen(filename,"r")) == NULL ) {
printf("Could not open %s",filename);
return -1;
}
if((debug=fopen("opjfile.log","w")) == NULL ) {
printf("Could not open log file!\n");
return -1;
}
////////////////////////////// check version from header ///////////////////////////////
char vers[5];
vers[4]=0;
// get version
fseek(f,0x7,SEEK_SET);
fread(&vers,4,1,f);
version = atoi(vers);
fprintf(debug," [version = %d]\n",version);
// translate version
if(version == 130) // 4.1
version=410;
else if(version == 210) // 5.0
version=500;
else if(version == 2625) // 6.0
version=600;
else if(version == 2627) // 6.0 SR1
version=601;
else if(version == 2630 ) // 6.0 SR4
version=604;
else if(version == 2635 ) // 6.1
version=610;
else if(version == 2656) // 7.0
version=700;
else if(version == 2769) // 7.5
version=750;
else {
fprintf(debug,"Found unknown project version %d\n",version);
fprintf(debug,"Please contact the author of opj2dat\n");
}
fprintf(debug,"Found project version %.2f\n",version/100.0);
// skip file header
char c=0;
fseek(f,0x16,SEEK_SET); // skip header + 5 Bytes ("27")
do{
fread(&c,1,1,f);
} while (c != '\n');
fprintf(debug," [file header @ 0x%X]\n", (unsigned int) ftell(f));
/////////////////// find column ///////////////////////////////////////////////////////////7
for(i=0;i<5;i++) // skip "0"
fread(&c,1,1,f);
int col_found;
fread(&col_found,4,1,f);
fread(&c,1,1,f); // skip '\n'
fprintf(debug," [column found = %d @ 0x%X]\n",col_found,(unsigned int) ftell(f));
int current_col=1, nr=0, nbytes=0;
double a;
char name[25], valuesize;
while(col_found > 0 && col_found < 132) { // should be 0x72, 0x73 or 0x83
//////////////////////////////// COLUMN HEADER /////////////////////////////////////////////
for(i=0;i<0x3D;i++) // skip to value size
fread(&c,1,1,f);
fread(&valuesize,1,1,f);
fprintf(debug," [valuesize = %d @ 0x%X]\n",valuesize,(unsigned int) ftell(f)-1);
if(valuesize <= 0) {
fprintf(debug," WARNING : found strange valuesize of %d\n",valuesize);
valuesize=10;
}
for(i=0;i<0x1A;i++) // skip to name
fread(&c,1,1,f);
// read name
fprintf(debug," [Spreadsheet @ 0x%X]\n",(unsigned int) ftell(f));
fflush(debug);
fread(&name,25,1,f);
char* sname = new char[26];
sprintf(sname,"%s",strtok(name,"_")); // spreadsheet name
char* cname = strtok(NULL,"_"); // column name
while(char* tmpstr = strtok(NULL,"_")) { // get multiple-"_" title correct
strcat(sname,"_");
strcat(sname,cname);
strcpy(cname,tmpstr);
}
if(nr_spreads == 0 || strcmp(sname,spreadname[nr_spreads-1])) {
fprintf(debug," NEW SPREADSHEET\n");
sprintf(spreadname[nr_spreads++],"%s",sname);
current_col=1;
maxrows[nr_spreads]=0;
}
else {
current_col++;
nr_cols[nr_spreads-1]=current_col;
}
fprintf(debug," SPREADSHEET = %s COLUMN NAME = %s (%d) (@0x%X)\n",
sname, cname,current_col,(unsigned int) ftell(f));
if(cname==0) {
fprintf(debug,"NO COLUMN FOUND! GIVING UP.\n");
fprintf(debug,"MAY BE MATRIX OR FUNCTION.\n");
nr_spreads-=1;
break;
}
sprintf(colname[nr_spreads-1][current_col-1],"%s",cname);
// NEW ? colname[nr_spreads-1][current_col-1]=cname;
////////////////////////////// SIZE of column /////////////////////////////////////////////
do{ // skip until '\n'
fread(&c,1,1,f);
} while (c != '\n');
fread(&nbytes,4,1,f);
if(fmod(nbytes,(double)valuesize)>0)
fprintf(debug,"WARNING: data section could not be read correct\n");
nr = nbytes / valuesize;
fprintf(debug," [number of rows = %d (%d Bytes) @ 0x%X]\n",nr,nbytes,(unsigned int) ftell(f));
nr_rows[nr_spreads-1][current_col-1]=nr;
maxrows[nr_spreads-1]<nr?maxrows[nr_spreads-1]=nr:0;
////////////////////////////////////// DATA ////////////////////////////////////////////////
fread(&c,1,1,f); // skip '\n'
if(valuesize != 8 && valuesize <= 16) { // skip 0 0
fread(&c,1,1,f);
fread(&c,1,1,f);
}
fprintf(debug," [data @ 0x%X]\n",(unsigned int) ftell(f));
data[nr_spreads-1][current_col-1] = (double *) malloc(nr*sizeof(double));
for (i=0;i<nr;i++) {
if(valuesize <= 16) { // value
fread(&a,valuesize,1,f);
fprintf(debug,"%g ",a);
data[nr_spreads-1][(current_col-1)][i]=a;
}
else { // label
char *stmp = new char[valuesize+1];
fread(stmp,valuesize,1,f);
fprintf(debug,"%s ",stmp);
sdata[nr_spreads-1][(current_col-1)][i] = stmp;
}
}
// fprintf(debug," [now @ 0x%X]\n",ftell(f));
fprintf(debug,"\n");
fflush(debug);
for(i=0;i<4;i++) // skip "0"
fread(&c,1,1,f);
if(valuesize == 8 || valuesize > 16) { // skip 0 0
fread(&c,1,1,f);
fread(&c,1,1,f);
}
fread(&col_found,4,1,f);
fread(&c,1,1,f); // skip '\n'
fprintf(debug," [column found = %d (@ 0x%X)]\n",col_found,(unsigned int) ftell(f)-5);
fflush(debug);
}
////////////////////////////////////// SPREADSHEETS ////////////////////////////////////////////////
// TODO : use new method ('\n')
int POS = ftell(f)-11;
fprintf(debug,"\n[position @ 0x%X]\n",POS);
fprintf(debug," nr_spreads = %d\n",nr_spreads);
fflush(debug);
///////////////////// SPREADSHEET INFOS ////////////////////////////////////
int LAYER;
int COL_JUMP = 0x1ED;
for(i=0; i < nr_spreads; i++) {
if(i > 0) {
if(version == 750)
POS = LAYER+0x2759;
else if (version == 700 )
POS += 0x2530 + nr_cols[i-1]*COL_JUMP;
else if (version == 610 )
POS += 0x25A4 + nr_cols[i-1]*COL_JUMP;
else if (version == 604 )
POS += 0x25A0 + nr_cols[i-1]*COL_JUMP;
else if (version == 601 )
POS += 0x2560 + nr_cols[i-1]*COL_JUMP; // ?
else if (version == 600 )
POS += 0x2560 + nr_cols[i-1]*COL_JUMP;
else if (version == 500 )
POS += 0x92C + nr_cols[i-1]*COL_JUMP;
else if (version == 410 )
POS += 0x7FB + nr_cols[i-1]*COL_JUMP;
}
fprintf(debug,"\n");
// HEADER
// check header
int ORIGIN = 0x55;
if(version == 500)
ORIGIN = 0x58;
fseek(f,POS + ORIGIN,SEEK_SET); // check for 'O'RIGIN
char c;
fread(&c,1,1,f);
int jump=0;
while( c != 'O' && jump < MAX_LEVEL) { // no inf loop
fprintf(debug," TRY %d \"O\"RIGIN not found ! : %c (@ 0x%X)",jump+1,c,POS+ORIGIN);
fprintf(debug," POS=0x%X | ORIGIN = 0x%X\n",POS,ORIGIN);
POS+=0x1F2;
fseek(f,POS + ORIGIN,SEEK_SET);
fread(&c,1,1,f);
jump++;
}
if(jump == MAX_LEVEL){
fprintf(debug," Spreadsheet SECTION not found ! (@ 0x%X)\n",POS-10*0x1F2+0x55);
return -5;
}
fprintf(debug," OK. Spreadsheet SECTION found (@ 0x%X)\n",POS);
fflush(debug);
// check spreadsheet name
fseek(f,POS + 0x12,SEEK_SET);
fread(&name,25,1,f);
int spread=i;
for(j=0;j<nr_spreads;j++) { // get index of spreadsheet
if(strncmp(name,spreadname[j],strlen(spreadname[j])) == 0)
spread=j;
}
fprintf(debug," SPREADSHEET %d NAME : %s (@ 0x%X) has %d columns\n",
spread+1,name,POS + 0x12,nr_cols[spread]);
int ATYPE;
LAYER = POS;
if(version == 750) {
// LAYER section
LAYER += 0x4AB;
ATYPE = 0xCF;
COL_JUMP = 0x1F2;
// seek for "L"ayerInfoStorage to find layer section
fseek(f,LAYER+0x53, SEEK_SET);
fread(&c,1,1,f);
while( c != 'L' && jump < MAX_LEVEL) { // no inf loop; number of "set column value"
LAYER += 0x99;
fseek(f,LAYER+0x53, SEEK_SET);
fread(&c,1,1,f);
jump++;
}
if(jump == MAX_LEVEL) {
fprintf(debug," LAYER %d SECTION not found !\nGiving up.",i+1);
return -3;
}
fprintf(debug," [LAYER %d @ 0x%X]\n",i+1,LAYER);
}
else if (version == 700)
ATYPE = 0x2E4;
else if (version == 610)
ATYPE = 0x358;
else if (version == 604)
ATYPE = 0x354;
else if (version == 601)
ATYPE = 0x500; // ?
else if (version == 600)
ATYPE = 0x314;
else if (version == 500) {
COL_JUMP=0x5D;
ATYPE = 0x300;
}
else if (version == 410) {
COL_JUMP = 0x58;
ATYPE = 0x229;
}
fflush(debug);
/////////////// COLUMN Types ///////////////////////////////////////////
for (j=0;j<nr_cols[spread];j++) {
fseek(f,LAYER+ATYPE+j*COL_JUMP, SEEK_SET);
fread(&name,25,1,f);
if(strncmp(name,colname[spread][j],strlen(colname[spread][j])) == 0) {
fseek(f,LAYER+ATYPE+j*COL_JUMP-1, SEEK_SET);
fread(&c,1,1,f);
char type[5];
switch(c) {
case 3: sprintf(type,"X");break;
case 0: sprintf(type,"Y");break;
case 5: sprintf(type,"Z");break;
case 6: sprintf(type,"DX");break;
case 2: sprintf(type,"DY");break;
case 4: sprintf(type,"LABEL");break;
default: sprintf(type,"NONE");break;
}
sprintf(coltype[spread][j],"%s",type);
fprintf(debug," COLUMN %s type = %s (@ 0x%X)\n",colname[spread][j],type,LAYER+ATYPE+j*COL_JUMP);
}
else {
fprintf(debug," COLUMN %d (%c) ? (@ 0x%X)\n",j+1,c,LAYER+ATYPE+j*COL_JUMP);
}
}
fflush(debug);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO : GRAPHS
/* int graph = 0x2fc1;
int pre_graph = 0x12;
fseek(f,graph + pre_graph,SEEK_SET);
fread(&name,25,1,f);
printf("GRAPH : %s\n",name);
fseek(f,graph + pre_graph + 0x43, SEEK_SET);
fread(&name,25,1,f);
printf("TYPE : %s\n",name);
fseek(f,graph + pre_graph + 0x2b3, SEEK_SET);
fread(&name,25,1,f);
printf("Y AXIS TITLE : %s\n",name);
fseek(f,graph + pre_graph + 0x38d, SEEK_SET);
fread(&name,25,1,f);
printf("X AXIS TITLE : %s\n",name);
fseek(f,graph + pre_graph + 0xadb, SEEK_SET);
fread(&name,25,1,f);
printf("LEGEND : %s\n",name);
*/
fclose(debug);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1