Logo Search packages:      
Sourcecode: qtiplot version File versions  Download package

OPJFile.cpp

/***************************************************************************
    File                 : OPJFile.cpp
    --------------------------------------------------------------------
    Copyright            : (C) 2005-2007 Stefan Gerlach
                                       (C) 2007 by Alex Kargovsky, Ion Vasilief
    Email (use @ for *)  : kargovsky*yumr.phys.msu.su, ion_vasilief*yahoo.fr
    Description          : Origin project import class

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *  This program is free software; you can redistribute it and/or modify   *
 *  it under the terms of the GNU General Public License as published by   *
 *  the Free Software Foundation; either version 2 of the License, or      *
 *  (at your option) any later version.                                    *
 *                                                                         *
 *  This program is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *  GNU General Public License for more details.                           *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the Free Software           *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
 *   Boston, MA  02110-1301  USA                                           *
 *                                                                         *
 ***************************************************************************/

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>

#include <algorithm> //required for std::swap
#include "OPJFile.h"

#define MAX_LEVEL 20
#define ERROR_MSG "Please send the OPJ file and the opjfile.log to the author of liborigin!\n"

#define SwapBytes(x) ByteSwap((unsigned char *) &x,sizeof(x))

int strcmp_i(const char *s1, const char *s2) { //compare two strings ignoring case
#ifdef _WINDOWS
      return stricmp(s1,s2);
#else
      return strcasecmp(s1,s2);
#endif
}

void OPJFile::ByteSwap(unsigned char * b, int n) {
      register int i = 0;
      register int j = n-1;
      while (i<j) {
            std::swap(b[i], b[j]);
            i++, j--;
      }
}

OPJFile::OPJFile(const char *filename)
      : filename(filename)
{
      version=0;
      dataIndex=0;
      objectIndex=0;
}

int OPJFile::compareSpreadnames(char *sname) const {
      for(unsigned int i=0;i<SPREADSHEET.size();i++)
            if (0==strcmp_i(SPREADSHEET[i].name.c_str(),sname))
                  return i;
      return -1;
}

int OPJFile::compareExcelnames(char *sname) const {
      for(unsigned int i=0;i<EXCEL.size();i++)
            if (0==strcmp_i(EXCEL[i].name.c_str(),sname))
                  return i;
      return -1;
}


int OPJFile::compareColumnnames(int spread, char *sname) const {
      for(unsigned int i=0;i<SPREADSHEET[spread].column.size();i++)
            if (SPREADSHEET[spread].column[i].name == sname)
                  return i;
      return -1;
}
int OPJFile::compareExcelColumnnames(int iexcel, int isheet, char *sname) const {
      for(unsigned int i=0;i<EXCEL[iexcel].sheet[isheet].column.size();i++)
            if (EXCEL[iexcel].sheet[isheet].column[i].name == sname)
                  return i;
      return -1;
}

int OPJFile::compareMatrixnames(char *sname) const {
      for(unsigned int i=0;i<MATRIX.size();i++)
            if (0==strcmp_i(MATRIX[i].name.c_str(),sname))
                  return i;
      return -1;
}

int OPJFile::compareFunctionnames(const char *sname) const {
      for(unsigned int i=0;i<FUNCTION.size();i++)
            if (0==strcmp_i(FUNCTION[i].name.c_str(),sname))
                  return i;
      return -1;
}

vector<string> OPJFile::findDataByIndex(int index) const {
      vector<string> str;
      for(unsigned int spread=0;spread<SPREADSHEET.size();spread++)
            for(unsigned int i=0;i<SPREADSHEET[spread].column.size();i++)
                  if (SPREADSHEET[spread].column[i].index == index)
                  {
                        str.push_back(SPREADSHEET[spread].column[i].name);
                        str.push_back("T_" + SPREADSHEET[spread].name);
                        return str;
                  }
      for(unsigned int i=0;i<MATRIX.size();i++)
            if (MATRIX[i].index == index)
            {
                  str.push_back(MATRIX[i].name);
                  str.push_back("M_" + MATRIX[i].name);
                  return str;
            }
      for(unsigned int i=0;i<EXCEL.size();i++)
            for(unsigned int j=0;j<EXCEL[i].sheet.size();j++)
                  for(unsigned int k=0;k<EXCEL[i].sheet[j].column.size();k++)
                        if (EXCEL[i].sheet[j].column[k].index == index)
                        {
                              str.push_back(EXCEL[i].sheet[j].column[k].name);
                              str.push_back("E_" + EXCEL[i].name);
                              return str;
                        }
      for(unsigned int i=0;i<FUNCTION.size();i++)
            if (FUNCTION[i].index == index)
            {
                  str.push_back(FUNCTION[i].name);
                  str.push_back("F_" + FUNCTION[i].name);
                  return str;
            }
      return str;
}

string OPJFile::findObjectByIndex(int index, string folder) {
      for(unsigned int i=0;i<SPREADSHEET.size();i++)
            if (SPREADSHEET[i].objectID == index)
            {
                  SPREADSHEET[i].parentFolder=folder;
                  return SPREADSHEET[i].name;
            }

      for(unsigned int i=0;i<MATRIX.size();i++)
            if (MATRIX[i].objectID == index)
            {
                  MATRIX[i].parentFolder=folder;
                  return MATRIX[i].name;
            }

      for(unsigned int i=0;i<EXCEL.size();i++)
            if (EXCEL[i].objectID == index)
            {
                  EXCEL[i].parentFolder=folder;
                  return EXCEL[i].name;
            }

      for(unsigned int i=0;i<GRAPH.size();i++)
            if (GRAPH[i].objectID == index)
            {
                  GRAPH[i].parentFolder=folder;
                  return GRAPH[i].name;
            }

      return "";
}

void OPJFile::convertSpreadToExcel(int spread)
{
      //add new Excel sheet
      EXCEL.push_back(excel(SPREADSHEET[spread].name, SPREADSHEET[spread].label, SPREADSHEET[spread].maxRows, SPREADSHEET[spread].bHidden, SPREADSHEET[spread].bLoose));
      for (unsigned int i=0; i<SPREADSHEET[spread].column.size(); ++i)
      {
            string name=SPREADSHEET[spread].column[i].name;
            int pos=name.find_last_of("@");
            string col=name;
            unsigned int index=0;
            if(pos!=-1)
            {
                  col=name.substr(0, pos);
                  index=atoi(name.substr(pos+1).c_str())-1;
            }

            if(EXCEL.back().sheet.size()<=index)
                  EXCEL.back().sheet.resize(index+1);
            SPREADSHEET[spread].column[i].name=col;
            EXCEL.back().sheet[index].column.push_back(SPREADSHEET[spread].column[i]);
      }
      SPREADSHEET.erase(SPREADSHEET.begin()+spread);
}
// set default name for columns starting from spreadsheet spread
void OPJFile::setColName(int spread) {
      for(unsigned int j=spread;j<SPREADSHEET.size();j++) {
            SPREADSHEET[j].column[0].type="X";
            for (unsigned int k=1;k<SPREADSHEET[j].column.size();k++)
                  SPREADSHEET[j].column[k].type="Y";
      }
}

/* File Structure :
filepre +
      + pre + head + data     col A
      + pre + head + data     col B
*/

/* parse file "filename" completely and save values */
int OPJFile::Parse() {
      FILE *f;
      if((f=fopen(filename,"rb")) == NULL ) {
            printf("Could not open %s!\n",filename);
            return -1;
      }

      char vers[5];
      vers[4]=0;

      // get version
      fseek(f,0x7,SEEK_SET);
      fread(&vers,4,1,f);
      fclose(f);
      version = atoi(vers);

      if(version >= 2766 && version <= 2769)    // 7.5
            return ParseFormatNew();
      else
            return ParseFormatOld();
}


int OPJFile::ParseFormatOld() {
      int i;
      FILE *f, *debug;
      if((f=fopen(filename,"rb")) == NULL ) {
            printf("Could not open %s!\n",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 && version <= 140)            // 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 == 2672)      // 7.0 SR3
            version=703;
      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);

      unsigned char c=0;      // tmp char

      fprintf(debug,"HEADER :\n");
      for(i=0;i<0x16;i++) {   // skip header + 5 Bytes ("27")
            fread(&c,1,1,f);
            fprintf(debug,"%.2X ",c);
            if(!((i+1)%16)) fprintf(debug,"\n");
      }
      fprintf(debug,"\n");

      do{
            fread(&c,1,1,f);
      } while (c != '\n');
      fprintf(debug,"   [file header @ 0x%X]\n", (unsigned int) ftell(f));

      /////////////////// find column ///////////////////////////////////////////////////////////
      if(version>410)
            for(i=0;i<5;i++)  // skip "0"
                  fread(&c,1,1,f);

      int col_found;
      fread(&col_found,4,1,f);
      if(IsBigEndian()) SwapBytes(col_found);

      fread(&c,1,1,f);  // skip '\n'
      fprintf(debug,"   [column found = %d/0x%X @ 0x%X]\n",col_found,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 < 0x84) {      // should be 0x72, 0x73 or 0x83
            //////////////////////////////// COLUMN HEADER /////////////////////////////////////////////
            fprintf(debug,"COLUMN HEADER :\n");
            for(i=0;i < 0x3D;i++) { // skip 0x3C chars to value size
                  fread(&c,1,1,f);
                  //if(i>21 && i<27) {
                  fprintf(debug,"%.2X ",c);
                  if(!((i+1)%16)) fprintf(debug,"\n");
                  //}
            }
            fprintf(debug,"\n");

            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;
            }

            fprintf(debug,"SKIP :\n");
            for(i=0;i<0x1A;i++) {   // skip to name
                  fread(&c,1,1,f);
                  fprintf(debug,"%.2X ",c);
                  if(!((i+1)%16)) fprintf(debug,"\n");
            }
            fprintf(debug,"\n");

            // read name
            fprintf(debug,"   [Spreadsheet @ 0x%X]\n",(unsigned int) ftell(f));
            fflush(debug);
            fread(&name,25,1,f);
            //char* sname = new char[26];
            char sname[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);
            }
            int spread=0;
            if(SPREADSHEET.size() == 0 || compareSpreadnames(sname) == -1) {
                  fprintf(debug,"NEW SPREADSHEET\n");
                  current_col=1;
                  SPREADSHEET.push_back(spreadSheet(sname));
                  spread=SPREADSHEET.size()-1;
                  SPREADSHEET.back().maxRows=0;
            }
            else {

                  spread=compareSpreadnames(sname);

                  current_col=SPREADSHEET[spread].column.size();

                  if(!current_col)
                        current_col=1;
                  current_col++;
            }
            fprintf(debug,"SPREADSHEET = %s COLUMN %d NAME = %s (@0x%X)\n",
                  sname, current_col, cname, (unsigned int) ftell(f));
            fflush(debug);

            if(cname == 0) {
                  fprintf(debug,"NO COLUMN NAME FOUND! Must be a matrix or function.\n");
                  ////////////////////////////// READ MATRIX or FUNCTION ////////////////////////////////////
                  fprintf(debug,"Reading MATRIX.\n");
                  fflush(debug);

                  fprintf(debug,"   [position @ 0x%X]\n",(unsigned int) ftell(f));
                  // TODO
                  fprintf(debug,"   SIGNATURE : ");
                  for(i=0;i<2;i++) {      // skip header
                        fread(&c,1,1,f);
                        fprintf(debug,"%.2X ",c);
                  }
                  fflush(debug);

                  do{   // skip until '\n'
                        fread(&c,1,1,f);
                        // fprintf(debug,"%.2X ",c);
                  } while (c != '\n');
                  fprintf(debug,"\n");
                  fflush(debug);

                  // read size
                  int size;
                  fread(&size,4,1,f);
                  fread(&c,1,1,f);  // skip '\n'
                  // TODO : use entry size : double, float, ...
                  size /= 8;
                  fprintf(debug,"   SIZE = %d\n",size);
                  fflush(debug);

                  // catch exception
                  if(size>10000)
                        size=1000;

                  fprintf(debug,"VALUES :\n");
                  SPREADSHEET[SPREADSHEET.size()-1].maxRows=1;

                  double value=0;
                  for(i=0;i<size;i++) {   // read data
                        string stmp;
                        if(i<26)
                              stmp=i+0x41;
                        else if(i<26*26) {
                              stmp = 0x40+i/26;
                              stmp[1] = i%26+0x41;
                        }
                        else {
                              stmp = 0x40+i/26/26;
                              stmp[1] = i/26%26+0x41;
                              stmp[2] = i%26+0x41;
                        }
                        SPREADSHEET[SPREADSHEET.size()-1].column.push_back(stmp);
                        fread(&value,8,1,f);
                        SPREADSHEET[SPREADSHEET.size()-1].column[i].odata.push_back(originData(value));

                        fprintf(debug,"%g ",value);
                  }
                  fprintf(debug,"\n");
                  fflush(debug);

            }
            else {      // worksheet
                  SPREADSHEET[spread].column.push_back(spreadColumn(cname));

                  ////////////////////////////// SIZE of column /////////////////////////////////////////////
                  do{   // skip until '\n'
                        fread(&c,1,1,f);
                  } while (c != '\n');

                  fread(&nbytes,4,1,f);
                  if(IsBigEndian()) SwapBytes(nbytes);
                  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));
                  fflush(debug);

                  SPREADSHEET[spread].maxRows<nr?SPREADSHEET[spread].maxRows=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));
                  fflush(debug);

                  for (i=0;i<nr;i++) {
                        if(valuesize <= 16) {   // value
                              fread(&a,valuesize,1,f);
                              if(IsBigEndian()) SwapBytes(a);
                              fprintf(debug,"%g ",a);
                              SPREADSHEET[spread].column[(current_col-1)].odata.push_back(originData(a));
                        }
                        else {                  // label
                              char *stmp = new char[valuesize+1];
                              fread(stmp,valuesize,1,f);
                              fprintf(debug,"%s ",stmp);
                              SPREADSHEET[spread].column[(current_col-1)].odata.push_back(originData(stmp));
                              delete stmp;
                        }
                  }
            }     // else
            //          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);
            if(IsBigEndian()) SwapBytes(col_found);
            fread(&c,1,1,f);  // skip '\n'
            fprintf(debug,"   [column found = %d/0x%X (@ 0x%X)]\n",col_found,col_found,(unsigned int) ftell(f)-5);
            fflush(debug);
      }

      ////////////////////// HEADER SECTION //////////////////////////////////////
      // TODO : use new method ('\n')

      int POS = ftell(f)-11;
      fprintf(debug,"\nHEADER SECTION\n");
      fprintf(debug,"   nr_spreads = %d\n",SPREADSHEET.size());
      fprintf(debug,"   [position @ 0x%X]\n",POS);
      fflush(debug);

///////////////////// SPREADSHEET INFOS ////////////////////////////////////
      int LAYER=0;
      int COL_JUMP = 0x1ED;
      for(unsigned int i=0; i < SPREADSHEET.size(); i++) {
      fprintf(debug,"         reading     Spreadsheet %d/%zd properties\n",i+1,SPREADSHEET.size());
      fflush(debug);
      if(i > 0) {
            if (version == 700 )
                  POS += 0x2530 + SPREADSHEET[i-1].column.size()*COL_JUMP;
            else if (version == 610 )
                  POS += 0x25A4 + SPREADSHEET[i-1].column.size()*COL_JUMP;
            else if (version == 604 )
                  POS += 0x25A0 + SPREADSHEET[i-1].column.size()*COL_JUMP;
            else if (version == 601 )
                  POS += 0x2560 + SPREADSHEET[i-1].column.size()*COL_JUMP;    // ?
            else if (version == 600 )
                  POS += 0x2560 + SPREADSHEET[i-1].column.size()*COL_JUMP;
            else if (version == 500 )
                  POS += 0x92C + SPREADSHEET[i-1].column.size()*COL_JUMP;
            else if (version == 410 )
                  POS += 0x7FB + SPREADSHEET[i-1].column.size()*COL_JUMP;
      }

      fprintf(debug,"               reading     Header\n");
      fflush(debug);
      // 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;
      if( c == 'O')
            fprintf(debug,"               \"ORIGIN\" found ! (@ 0x%X)\n",POS+ORIGIN);
      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);
            fflush(debug);
            POS+=0x1F2;
            fseek(f,POS + ORIGIN,SEEK_SET);
            fread(&c,1,1,f);
            jump++;
      }

      int spread=i;
      if(jump == MAX_LEVEL){
            fprintf(debug,"         Spreadsheet SECTION not found !     (@ 0x%X)\n",POS-10*0x1F2+0x55);
            // setColName(spread);
            return -5;
      }

      fprintf(debug,"               [Spreadsheet SECTION (@ 0x%X)]\n",POS);
      fflush(debug);

      // check spreadsheet name
      fseek(f,POS + 0x12,SEEK_SET);
      fread(&name,25,1,f);

      spread=compareSpreadnames(name);
      if(spread == -1)
            spread=i;

      fprintf(debug,"               SPREADSHEET %d NAME : %s      (@ 0x%X) has %d columns\n",
            spread+1,name,POS + 0x12,SPREADSHEET[spread].column.size());
      fflush(debug);

      int ATYPE=0;
      LAYER = POS;
      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 ///////////////////////////////////////////
      fprintf(debug,"               Spreadsheet has %d columns\n",SPREADSHEET[spread].column.size());
      for (unsigned int j=0;j<SPREADSHEET[spread].column.size();j++) {
            fprintf(debug,"               reading     COLUMN %d/%zd type\n",j+1,SPREADSHEET[spread].column.size());
            fflush(debug);
            fseek(f,LAYER+ATYPE+j*COL_JUMP, SEEK_SET);
            fread(&name,25,1,f);

            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;
            }

            SPREADSHEET[spread].column[j].type=type;

            fprintf(debug,"                     COLUMN \"%s\" type = %s (@ 0x%X)\n",
                  SPREADSHEET[spread].column[j].name.c_str(),type,LAYER+ATYPE+j*COL_JUMP);
            fflush(debug);

            // check column name
            int max_length=11;      // only first 11 chars are saved here !
            int name_length = SPREADSHEET[spread].column[j].name.length();
                    int length = (name_length < max_length) ? name_length : max_length;

            if(SPREADSHEET[spread].column[j].name.substr(0,length) == name) {
                  fprintf(debug,"                     TEST : column name = \"%s\". OK!\n",
                        SPREADSHEET[spread].column[j].name.c_str());
            }
            else {
                  fprintf(debug,"                     TEST : COLUMN %d name mismatch (\"%s\" != \"%s\")\n",
                        j+1,name,SPREADSHEET[spread].column[j].name.c_str());
                  //fprintf(debug,"ERROR : column name mismatch! Continue anyway.\n"ERROR_MSG);
            }
            fflush(debug);
      }
            fprintf(debug,"         Done with spreadsheet %d\n",spread);
            fflush(debug);
      }

///////////////////////////////////////////////////////////////////////////////////////////////////////////

      // TODO : GRAPHS

      fprintf(debug,"Done parsing\n");
      fclose(debug);

      return 0;
}


int OPJFile::ParseFormatNew() {
      int i;
      FILE *f, *debug;
      if((f=fopen(filename,"rb")) == NULL ) {
            printf("Could not open %s!\n",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 && version <= 140)            // 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 == 2672)      // 7.0 SR3
            version=703;
      else if(version >= 2766 && 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);

      unsigned char c=0;      // tmp char

      fprintf(debug,"HEADER :\n");
      for(i=0;i<0x16;i++) {   // skip header + 5 Bytes ("27")
            fread(&c,1,1,f);
            fprintf(debug,"%.2X ",c);
            if(!((i+1)%16)) fprintf(debug,"\n");
      }
      fprintf(debug,"\n");

      do{
            fread(&c,1,1,f);
      } while (c != '\n');
      fprintf(debug,"   [file header @ 0x%X]\n", (unsigned int) ftell(f));

/////////////////// find column ///////////////////////////////////////////////////////////
      if(version>410)
            for(i=0;i<5;i++)  // skip "0"
                  fread(&c,1,1,f);

      int col_found;
      fread(&col_found,4,1,f);
      if(IsBigEndian()) SwapBytes(col_found);

      fread(&c,1,1,f);  // skip '\n'
      fprintf(debug,"   [column found = %d/0x%X @ 0x%X]\n",col_found,col_found,(unsigned int) ftell(f));
      int colpos=ftell(f);

      int current_col=1, nr=0, nbytes=0;
      double a;
      char name[25], valuesize;
      while(col_found > 0 && col_found < 0x84) {      // should be 0x72, 0x73 or 0x83
//////////////////////////////// COLUMN HEADER /////////////////////////////////////////////
            short data_type;
            char data_type_u;
            int oldpos=ftell(f);
            fseek(f,oldpos+0x16,SEEK_SET);
            fread(&data_type,2,1,f);
            if(IsBigEndian()) SwapBytes(data_type);
            fseek(f,oldpos+0x3F,SEEK_SET);
            fread(&data_type_u,1,1,f);
            fseek(f,oldpos,SEEK_SET);

            fprintf(debug,"COLUMN HEADER :\n");
            for(i=0;i < 0x3D;i++) { // skip 0x3C chars to value size
                  fread(&c,1,1,f);
                  //if(i>21 && i<27) {
                        fprintf(debug,"%.2X ",c);
                        if(!((i+1)%16)) fprintf(debug,"\n");
                  //}
            }
            fprintf(debug,"\n");

            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;
            }

            fprintf(debug,"SKIP :\n");
            for(i=0;i<0x1A;i++) {   // skip to name
                  fread(&c,1,1,f);
                  fprintf(debug,"%.2X ",c);
                  if(!((i+1)%16)) fprintf(debug,"\n");
            }
            fprintf(debug,"\n");

            // read name
            fprintf(debug,"   [Spreadsheet @ 0x%X]\n",(unsigned int) ftell(f));
            fflush(debug);
            fread(&name,25,1,f);
            //char* sname = new char[26];
            char sname[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);
            }
            int spread=0;
            if(cname == 0) {
                  fprintf(debug,"NO COLUMN NAME FOUND! Must be a matrix or function.\n");
////////////////////////////// READ MATRIX or FUNCTION ////////////////////////////////////

                  fprintf(debug,"   [position @ 0x%X]\n",(unsigned int) ftell(f));
                  // TODO
                  short signature;
                  fread(&signature,2,1,f);
                  if(IsBigEndian()) SwapBytes(signature);
                  fprintf(debug,"   SIGNATURE : ");
                  fprintf(debug,"%.2X ",signature);
                  fflush(debug);

                  do{   // skip until '\n'
                        fread(&c,1,1,f);
                        // fprintf(debug,"%.2X ",c);
                  } while (c != '\n');
                  fprintf(debug,"\n");
                  fflush(debug);

                  // read size
                  int size;
                  fread(&size,4,1,f);
                  if(IsBigEndian()) SwapBytes(size);
                  fread(&c,1,1,f);  // skip '\n'
                  // TODO : use entry size : double, float, ...
                  size /= valuesize;
                  fprintf(debug,"   SIZE = %d\n",size);
                  fflush(debug);

                  // catch exception
                  /*if(size>10000)
                        size=1000;*/
                  switch(signature)
                  {
                  case 0x50CA:
                  case 0x70CA:
                  case 0x50F2:
                  case 0x50E2:
                        fprintf(debug,"NEW MATRIX\n");
                        MATRIX.push_back(matrix(sname, dataIndex));
                        dataIndex++;

                        fprintf(debug,"VALUES :\n");

                        switch(data_type)
                        {
                        case 0x6001://double
                              for(i=0;i<size;i++) {
                                    double value;
                                    fread(&value,valuesize,1,f);
                                    if(IsBigEndian()) SwapBytes(value);
                                    MATRIX.back().data.push_back((double)value);
                                    fprintf(debug,"%g ",MATRIX.back().data.back());
                              }
                              break;
                        case 0x6003://float
                              for(i=0;i<size;i++) {
                                    float value;
                                    fread(&value,valuesize,1,f);
                                    if(IsBigEndian()) SwapBytes(value);
                                    MATRIX.back().data.push_back((double)value);
                                    fprintf(debug,"%g ",MATRIX.back().data.back());
                              }
                              break;
                        case 0x6801://int
                              if(data_type_u==8)//unsigned
                                    for(i=0;i<size;i++) {
                                          unsigned int value;
                                          fread(&value,valuesize,1,f);
                                          if(IsBigEndian()) SwapBytes(value);
                                          MATRIX.back().data.push_back((double)value);
                                          fprintf(debug,"%g ",MATRIX.back().data.back());
                                    }
                              else
                                    for(i=0;i<size;i++) {
                                          int value;
                                          fread(&value,valuesize,1,f);
                                          if(IsBigEndian()) SwapBytes(value);
                                          MATRIX.back().data.push_back((double)value);
                                          fprintf(debug,"%g ",MATRIX.back().data.back());
                                    }
                              break;
                        case 0x6803://short
                              if(data_type_u==8)//unsigned
                                    for(i=0;i<size;i++) {
                                          unsigned short value;
                                          fread(&value,valuesize,1,f);
                                          if(IsBigEndian()) SwapBytes(value);
                                          MATRIX.back().data.push_back((double)value);
                                          fprintf(debug,"%g ",MATRIX.back().data.back());
                                    }
                              else
                                    for(i=0;i<size;i++) {
                                          short value;
                                          fread(&value,valuesize,1,f);
                                          if(IsBigEndian()) SwapBytes(value);
                                          MATRIX.back().data.push_back((double)value);
                                          fprintf(debug,"%g ",MATRIX.back().data.back());
                                    }
                              break;
                        case 0x6821://char
                              if(data_type_u==8)//unsigned
                                    for(i=0;i<size;i++) {
                                          unsigned char value;
                                          fread(&value,valuesize,1,f);
                                          if(IsBigEndian()) SwapBytes(value);
                                          MATRIX.back().data.push_back((double)value);
                                          fprintf(debug,"%g ",MATRIX.back().data.back());
                                    }
                              else
                                    for(i=0;i<size;i++) {
                                          char value;
                                          fread(&value,valuesize,1,f);
                                          if(IsBigEndian()) SwapBytes(value);
                                          MATRIX.back().data.push_back((double)value);
                                          fprintf(debug,"%g ",MATRIX.back().data.back());
                                    }
                              break;
                        default:
                              fprintf(debug,"UNKNOWN MATRIX DATATYPE: %.2X SKIP DATA\n", data_type);
                              fseek(f, valuesize*size, SEEK_CUR);
                              MATRIX.pop_back();
                        }

                        break;
                  case 0x10C8:
                        fprintf(debug,"NEW FUNCTION\n");
                        FUNCTION.push_back(function(sname, dataIndex));
                        dataIndex++;

                        char *cmd;
                        cmd=new char[valuesize+1];
                        cmd[valuesize]='\0';
                        fread(cmd,valuesize,1,f);
                        FUNCTION.back().formula=cmd;
                        int oldpos;
                        oldpos=ftell(f);
                        short t;
                        fseek(f,colpos+0xA,SEEK_SET);
                        fread(&t,2,1,f);
                        if(IsBigEndian()) SwapBytes(t);
                        if(t==0x1194)
                              FUNCTION.back().type=1;
                        int N;
                        fseek(f,colpos+0x21,SEEK_SET);
                        fread(&N,4,1,f);
                        if(IsBigEndian()) SwapBytes(N);
                        FUNCTION.back().points=N;
                        double d;
                        fread(&d,8,1,f);
                        if(IsBigEndian()) SwapBytes(d);
                        FUNCTION.back().begin=d;
                        fread(&d,8,1,f);
                        if(IsBigEndian()) SwapBytes(d);
                        FUNCTION.back().end=FUNCTION.back().begin+d*(FUNCTION.back().points-1);
                        fprintf(debug,"FUNCTION %s : %s \n", FUNCTION.back().name.c_str(), FUNCTION.back().formula.c_str());
                        fprintf(debug," interval %g : %g, number of points %d \n", FUNCTION.back().begin, FUNCTION.back().end, FUNCTION.back().points);
                        fseek(f,oldpos,SEEK_SET);

                        delete [] cmd;
                        break;
                  default:
                        fprintf(debug,"UNKNOWN SIGNATURE: %.2X SKIP DATA\n", signature);
                        fseek(f, valuesize*size, SEEK_CUR);
                        if(valuesize != 8 && valuesize <= 16)
                              fseek(f, 2, SEEK_CUR);
                  }

                  fprintf(debug,"\n");
                  fflush(debug);
            }
            else {      // worksheet
                  if(SPREADSHEET.size() == 0 || compareSpreadnames(sname) == -1) {
                        fprintf(debug,"NEW SPREADSHEET\n");
                        current_col=1;
                        SPREADSHEET.push_back(spreadSheet(sname));
                        spread=SPREADSHEET.size()-1;
                        SPREADSHEET.back().maxRows=0;
                  }
                  else {

                        spread=compareSpreadnames(sname);

                        current_col=SPREADSHEET[spread].column.size();

                        if(!current_col)
                              current_col=1;
                        current_col++;
                  }
                  fprintf(debug,"SPREADSHEET = %s COLUMN NAME = %s (%d) (@0x%X)\n",
                        sname, cname,current_col,(unsigned int) ftell(f));
                  fflush(debug);
                  SPREADSHEET[spread].column.push_back(spreadColumn(cname, dataIndex));
                  int sheetpos=SPREADSHEET[spread].column.back().name.find_last_of("@");
                  if(!SPREADSHEET[spread].bMultisheet && sheetpos!=-1)
                        if(atoi(string(cname).substr(sheetpos+1).c_str())>1)
                        {
                              SPREADSHEET[spread].bMultisheet=true;
                              fprintf(debug,"SPREADSHEET \"%s\" IS MULTISHEET \n", sname);
                        }
                  dataIndex++;

////////////////////////////// SIZE of column /////////////////////////////////////////////
                  do{   // skip until '\n'
                        fread(&c,1,1,f);
                  } while (c != '\n');

                  fread(&nbytes,4,1,f);
                  if(IsBigEndian()) SwapBytes(nbytes);
                  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));
                  fflush(debug);

                  SPREADSHEET[spread].maxRows<nr?SPREADSHEET[spread].maxRows=nr:0;

////////////////////////////////////// DATA ////////////////////////////////////////////////
                  fread(&c,1,1,f);  // skip '\n'
                  /*if(valuesize != 8 && valuesize <= 16 && nbytes>0) { // skip 0 0
                        fread(&c,1,1,f);
                        fread(&c,1,1,f);
                  }*/
                  fprintf(debug,"   [data @ 0x%X]\n",(unsigned int) ftell(f));
                  fflush(debug);

                  for (i=0;i<nr;i++) {
                        if(valuesize <= 8) {    // Numeric, Time, Date, Month, Day
                              fread(&a,valuesize,1,f);
                              if(IsBigEndian()) SwapBytes(a);
                              fprintf(debug,"%g ",a);
                              SPREADSHEET[spread].column[(current_col-1)].odata.push_back(originData(a));
                        }
                        else if((data_type&0x100)==0x100) // Text&Numeric
                        {
                              fread(&c,1,1,f);
                              fseek(f,1,SEEK_CUR);
                              if(c==0) //value
                              {
                                    //fread(&a,valuesize-2,1,f);
                                    fread(&a,8,1,f);
                                    if(IsBigEndian()) SwapBytes(a);
                                    fprintf(debug,"%g ",a);
                                    SPREADSHEET[spread].column[(current_col-1)].odata.push_back(originData(a));
                                    fseek(f,valuesize-10,SEEK_CUR);
                              }
                              else //text
                              {
                                    char *stmp = new char[valuesize-1];
                                    fread(stmp,valuesize-2,1,f);
                                    if(strchr(stmp,0x0E)) // try find non-printable symbol - garbage test
                                          stmp[0]='\0';
                                    SPREADSHEET[spread].column[(current_col-1)].odata.push_back(originData(stmp));
                                    fprintf(debug,"%s ",stmp);
                                    delete stmp;
                              }
                        }
                        else //Text
                        {
                              char *stmp = new char[valuesize+1];
                              fread(stmp,valuesize,1,f);
                              if(strchr(stmp,0x0E)) // try find non-printable symbol - garbage test
                                    stmp[0]='\0';
                              SPREADSHEET[spread].column[(current_col-1)].odata.push_back(originData(stmp));
                              fprintf(debug,"%s ",stmp);
                              delete stmp;
                        }
                  }

            }     // else

            fprintf(debug,"\n");
            fflush(debug);

            if(nbytes>0||cname==0)
                  fseek(f,1,SEEK_CUR);

            int tailsize;
            fread(&tailsize,4,1,f);
            if(IsBigEndian()) SwapBytes(tailsize);
            fseek(f,1+tailsize+(tailsize>0?1:0),SEEK_CUR); //skip tail
            //fseek(f,5+((nbytes>0||cname==0)?1:0),SEEK_CUR);
            fread(&col_found,4,1,f);
            if(IsBigEndian()) SwapBytes(col_found);
            fseek(f,1,SEEK_CUR);    // skip '\n'
            fprintf(debug,"   [column found = %d/0x%X (@ 0x%X)]\n",col_found,col_found,(unsigned int) ftell(f)-5);
            colpos=ftell(f);
            fflush(debug);
      }

////////////////////////////////////////////////////////////////////////////
      for(unsigned int i=0; i<SPREADSHEET.size(); ++i)
            if(SPREADSHEET[i].bMultisheet)
            {
                  fprintf(debug,"         CONVERT SPREADSHEET \"%s\" to EXCEL\n", SPREADSHEET[i].name.c_str());
                  fflush(debug);
                  convertSpreadToExcel(i);
                  i--;
            }
////////////////////////////////////////////////////////////////////////////
////////////////////// HEADER SECTION //////////////////////////////////////

      int POS = ftell(f)-11;
      fprintf(debug,"\nHEADER SECTION\n");
      fprintf(debug,"   nr_spreads = %d\n",SPREADSHEET.size());
      fprintf(debug,"   [position @ 0x%X]\n",POS);
      fflush(debug);

//////////////////////// OBJECT INFOS //////////////////////////////////////
      POS+=0xB;
      fseek(f,POS,SEEK_SET);
      while(1) {

            fprintf(debug,"               reading     Header\n");
            fflush(debug);
            // HEADER
            // check header
            POS=ftell(f);
            int headersize;
            fread(&headersize,4,1,f);
            if(IsBigEndian()) SwapBytes(headersize);
            if(headersize==0)
                  break;
            char object_type[10];
            char object_name[25];
            fseek(f,POS + 0x7,SEEK_SET);
            fread(&object_name,25,1,f);
            fseek(f,POS + 0x4A,SEEK_SET);
            fread(&object_type,10,1,f);

            fseek(f,POS,SEEK_SET);

            if(compareSpreadnames(object_name)!=-1)
                  readSpreadInfo(f, debug);
            else if(compareMatrixnames(object_name)!=-1)
                  readMatrixInfo(f, debug);
            else if(compareExcelnames(object_name)!=-1)
                  readExcelInfo(f, debug);
            else
                  readGraphInfo(f, debug);
      }



      fseek(f,1,SEEK_CUR);
      fprintf(debug,"Some Origin params @ 0x%X:\n", (unsigned int)ftell(f));
      fread(&c,1,1,f);
      while(c!=0)
      {
            fprintf(debug,"         ");
            while(c!='\n'){
                  fprintf(debug,"%c",c);
                  fread(&c,1,1,f);
            }
            double parvalue;
            fread(&parvalue,8,1,f);
            if(IsBigEndian()) SwapBytes(parvalue);
            fprintf(debug,": %g\n", parvalue);
            fseek(f,1,SEEK_CUR);
            fread(&c,1,1,f);
      }
      fseek(f,1+5,SEEK_CUR);
      while(1)
      {
            //fseek(f,5+0x40+1,SEEK_CUR);
            int size;
            fread(&size,4,1,f);
            if(IsBigEndian()) SwapBytes(size);
            if(size!=0x40)
                  break;
            fseek(f,1+0x40-4,SEEK_CUR);
            unsigned char labellen;
            fread(&labellen,1,1,f);

            fseek(f,4,SEEK_CUR);
            fread(&size,4,1,f);
            if(IsBigEndian()) SwapBytes(size);
            fseek(f,1,SEEK_CUR);
            char *stmp = new char[size+1];
            fread(stmp,size,1,f);
            if(0==strcmp(stmp,"ResultsLog"))
            {
                  delete stmp;
                  fseek(f,1,SEEK_CUR);
                  fread(&size,4,1,f);
                  if(IsBigEndian()) SwapBytes(size);
                  fseek(f,1,SEEK_CUR);
                  stmp = new char[size+1];
                  fread(stmp,size,1,f);
                  resultsLog=stmp;
                  fprintf(debug,"Results Log: %s\n", resultsLog.c_str());
                  delete stmp;
                  break;
            }
            else
            {
                  NOTE.push_back(note(stmp));
                  NOTE.back().objectID=objectIndex;
                  objectIndex++;
                  delete stmp;
                  fseek(f,1,SEEK_CUR);
                  fread(&size,4,1,f);
                  if(IsBigEndian()) SwapBytes(size);
                  fseek(f,1,SEEK_CUR);
                  if(labellen>1)
                  {
                        stmp = new char[labellen];
                        stmp[labellen-1]='\0';
                        fread(stmp,labellen-1,1,f);
                        NOTE.back().label=stmp;
                        delete stmp;
                        fseek(f,1,SEEK_CUR);
                  }
                  stmp = new char[size-labellen+1];
                  fread(stmp,size-labellen,1,f);
                  NOTE.back().text=stmp;
                  fprintf(debug,"NOTE %d NAME: %s\n", NOTE.size(), NOTE.back().name.c_str());
                  fprintf(debug,"NOTE %d LABEL: %s\n", NOTE.size(), NOTE.back().label.c_str());
                  fprintf(debug,"NOTE %d TEXT:\n%s\n", NOTE.size(), NOTE.back().text.c_str());
                  delete stmp;
                  fseek(f,1,SEEK_CUR);
            }
      }

      fseek(f,1+4*5+0x10+1,SEEK_CUR);
      try{
            readProjectTree(f, debug);
      }
      catch(...)
      {}
      fprintf(debug,"Done parsing\n");
      fclose(debug);

      return 0;
}

void OPJFile::readSpreadInfo(FILE *f, FILE *debug)
{
      int POS=ftell(f);

      int headersize;
      fread(&headersize,4,1,f);
      if(IsBigEndian()) SwapBytes(headersize);

      POS+=5;

      fprintf(debug,"               [Spreadsheet SECTION (@ 0x%X)]\n",POS);
      fflush(debug);

      // check spreadsheet name
      char name[25];
      fseek(f,POS + 0x2,SEEK_SET);
      fread(&name,25,1,f);

      int spread=compareSpreadnames(name);
      SPREADSHEET[spread].name=name;
      readWindowProperties(SPREADSHEET[spread], f, debug, POS, headersize);
      SPREADSHEET[spread].bLoose=false;
      char c = 0;

      int LAYER = POS;
      {
            // LAYER section
            LAYER += headersize + 0x1 + 0x5/* length of block = 0x12D + '\n'*/ + 0x12D + 0x1;
            //now structure is next : section_header_size=0x6F(4 bytes) + '\n' + section_header(0x6F bytes) + section_body_1_size(4 bytes) + '\n' + section_body_1 + section_body_2_size(maybe=0)(4 bytes) + '\n' + section_body_2 + '\n'
            //possible sections: column formulas, __WIPR, __WIOTN, __LayerInfoStorage etc
            //section name(column name in formula case) starts with 0x46 position
            while(1)
            {
                  int sec_size;
            //section_header_size=0x6F(4 bytes) + '\n'
                  LAYER+=0x5;

            //section_header
                  fseek(f,LAYER+0x46,SEEK_SET);
                  char sec_name[42];
                  sec_name[41]='\0';
                  fread(&sec_name,41,1,f);

                  fprintf(debug,"                     DEBUG SECTION NAME: %s (@ 0x%X)\n", sec_name, LAYER+0x46);
                  fflush(debug);

            //section_body_1_size
                  LAYER+=0x6F+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_1
                  LAYER+=0x5;
                  fseek(f,LAYER,SEEK_SET);
                  //check if it is a formula
                  int col_index=compareColumnnames(spread,sec_name);
                  if(col_index!=-1)
                  {
                        char *stmp=new char[sec_size+1];
                        stmp[sec_size]='\0';
                        fread(stmp,sec_size,1,f);
                        SPREADSHEET[spread].column[col_index].command=stmp;
                        delete stmp;
                  }

            //section_body_2_size
                  LAYER+=sec_size+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_2
                  LAYER+=0x5;

            //close section 00 00 00 00 0A
                  LAYER+=sec_size+(sec_size>0?0x1:0)+0x5;

                  if(0==strcmp(sec_name,"__LayerInfoStorage"))
                        break;

            }
            LAYER+=0x5;

      }

      fflush(debug);

      /////////////// COLUMN Types ///////////////////////////////////////////
      fprintf(debug,"               Spreadsheet has %d columns\n",SPREADSHEET[spread].column.size());

      while(1)
      {
            LAYER+=0x5;
            fseek(f,LAYER+0x12, SEEK_SET);
            fread(&name,12,1,f);

            fseek(f,LAYER+0x11, SEEK_SET);
            fread(&c,1,1,f);
            short width=0;
            fseek(f,LAYER+0x4A, SEEK_SET);
            fread(&width,2,1,f);
            if(IsBigEndian()) SwapBytes(width);
            int col_index=compareColumnnames(spread,name);
            if(col_index!=-1)
            {
                  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;
                  }
                  SPREADSHEET[spread].column[col_index].type=type;
                  width/=0xA;
                  if(width==0)
                        width=8;
                  SPREADSHEET[spread].column[col_index].width=width;
                  fseek(f,LAYER+0x1E, SEEK_SET);
                  unsigned char c1,c2;
                  fread(&c1,1,1,f);
                  fread(&c2,1,1,f);
                  switch(c1)
                  {
                  case 0x00: // Numeric      - Dec1000
                  case 0x09: // Text&Numeric - Dec1000
                  case 0x10: // Numeric      - Scientific
                  case 0x19: // Text&Numeric - Scientific
                  case 0x20: // Numeric      - Engeneering
                  case 0x29: // Text&Numeric - Engeneering
                  case 0x30: // Numeric      - Dec1,000
                  case 0x39: // Text&Numeric - Dec1,000
                        SPREADSHEET[spread].column[col_index].value_type=(c1%0x10==0x9)?6:0;
                        SPREADSHEET[spread].column[col_index].value_type_specification=c1/0x10;
                        if(c2>=0x80)
                        {
                              SPREADSHEET[spread].column[col_index].significant_digits=c2-0x80;
                              SPREADSHEET[spread].column[col_index].numeric_display_type=2;
                        }
                        else if(c2>0)
                        {
                              SPREADSHEET[spread].column[col_index].decimal_places=c2-0x03;
                              SPREADSHEET[spread].column[col_index].numeric_display_type=1;
                        }
                        break;
                  case 0x02: // Time
                        SPREADSHEET[spread].column[col_index].value_type=3;
                        SPREADSHEET[spread].column[col_index].value_type_specification=c2-0x80;
                        break;
                  case 0x03: // Date
                        SPREADSHEET[spread].column[col_index].value_type=2;
                        SPREADSHEET[spread].column[col_index].value_type_specification=c2-0x80;
                        break;
                  case 0x31: // Text
                        SPREADSHEET[spread].column[col_index].value_type=1;
                        break;
                  case 0x4: // Month
                  case 0x34:
                        SPREADSHEET[spread].column[col_index].value_type=4;
                        SPREADSHEET[spread].column[col_index].value_type_specification=c2;
                        break;
                  case 0x5: // Day
                  case 0x35:
                        SPREADSHEET[spread].column[col_index].value_type=5;
                        SPREADSHEET[spread].column[col_index].value_type_specification=c2;
                        break;
                  default: // Text
                        SPREADSHEET[spread].column[col_index].value_type=1;
                        break;
                  }
                  fprintf(debug,"                     COLUMN \"%s\" type = %s(%d) (@ 0x%X)\n",
                        SPREADSHEET[spread].column[col_index].name.c_str(),type,c,LAYER+0x11);
                  fflush(debug);
            }
            LAYER+=0x1E7+0x1;
            fseek(f,LAYER,SEEK_SET);
            int comm_size=0;
            fread(&comm_size,4,1,f);
            if(IsBigEndian()) SwapBytes(comm_size);
            LAYER+=0x5;
            if(comm_size>0)
            {
                  char* comment=new char[comm_size+1];
                  comment[comm_size]='\0';
                  fseek(f,LAYER,SEEK_SET);
                  fread(comment,comm_size,1,f);
                  if(col_index!=-1)
                        SPREADSHEET[spread].column[col_index].comment=comment;
                  LAYER+=comm_size+0x1;
                  delete comment;
            }
            fseek(f,LAYER,SEEK_SET);
            int ntmp;
            fread(&ntmp,4,1,f);
            if(IsBigEndian()) SwapBytes(ntmp);
            if(ntmp!=0x1E7)
                  break;
      }
      fprintf(debug,"         Done with spreadsheet %d\n",spread);
      fflush(debug);

      POS = LAYER+0x5*0x6+0x1ED*0x12;
      fseek(f,POS,SEEK_SET);
}

void OPJFile::readExcelInfo(FILE *f, FILE *debug)
{
      int POS=ftell(f);

      int headersize;
      fread(&headersize,4,1,f);
      if(IsBigEndian()) SwapBytes(headersize);

      POS+=5;

      fprintf(debug,"               [EXCEL SECTION (@ 0x%X)]\n",POS);
      fflush(debug);

      // check spreadsheet name
      char name[25];
      fseek(f,POS + 0x2,SEEK_SET);
      fread(&name,25,1,f);

      int iexcel=compareExcelnames(name);
      EXCEL[iexcel].name=name;
      readWindowProperties(EXCEL[iexcel], f, debug, POS, headersize);
      EXCEL[iexcel].bLoose=false;
      char c = 0;

      int LAYER = POS;
      LAYER += headersize + 0x1;
      int sec_size;
      int isheet=0;
      while(1)// multisheet loop
      {
            // LAYER section
            LAYER += 0x5/* length of block = 0x12D + '\n'*/ + 0x12D + 0x1;
            //now structure is next : section_header_size=0x6F(4 bytes) + '\n' + section_header(0x6F bytes) + section_body_1_size(4 bytes) + '\n' + section_body_1 + section_body_2_size(maybe=0)(4 bytes) + '\n' + section_body_2 + '\n'
            //possible sections: column formulas, __WIPR, __WIOTN, __LayerInfoStorage etc
            //section name(column name in formula case) starts with 0x46 position
            while(1)
            {
            //section_header_size=0x6F(4 bytes) + '\n'
                  LAYER+=0x5;

            //section_header
                  fseek(f,LAYER+0x46,SEEK_SET);
                  char sec_name[42];
                  sec_name[41]='\0';
                  fread(&sec_name,41,1,f);

                  fprintf(debug,"                     DEBUG SECTION NAME: %s (@ 0x%X)\n", sec_name, LAYER+0x46);
                  fflush(debug);

            //section_body_1_size
                  LAYER+=0x6F+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_1
                  LAYER+=0x5;
                  fseek(f,LAYER,SEEK_SET);
                  //check if it is a formula
                  int col_index=compareExcelColumnnames(iexcel, isheet, sec_name);
                  if(col_index!=-1)
                  {
                        char *stmp=new char[sec_size+1];
                        stmp[sec_size]='\0';
                        fread(stmp,sec_size,1,f);
                        EXCEL[iexcel].sheet[isheet].column[col_index].command=stmp;
                        delete stmp;
                  }

            //section_body_2_size
                  LAYER+=sec_size+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_2
                  LAYER+=0x5;

            //close section 00 00 00 00 0A
                  LAYER+=sec_size+(sec_size>0?0x1:0)+0x5;

                  if(0==strcmp(sec_name,"__LayerInfoStorage"))
                        break;

            }
            LAYER+=0x5;

            fflush(debug);

            /////////////// COLUMN Types ///////////////////////////////////////////
            fprintf(debug,"               Excel sheet %d has %d columns\n",isheet,EXCEL[iexcel].sheet[isheet].column.size());

            while(1)
            {
                  LAYER+=0x5;
                  fseek(f,LAYER+0x12, SEEK_SET);
                  fread(&name,12,1,f);

                  fseek(f,LAYER+0x11, SEEK_SET);
                  fread(&c,1,1,f);
                  short width=0;
                  fseek(f,LAYER+0x4A, SEEK_SET);
                  fread(&width,2,1,f);
                  if(IsBigEndian()) SwapBytes(width);
                  //char col_name[30];
                  //sprintf(col_name, "%s@%d", name, isheet);
                  int col_index=compareExcelColumnnames(iexcel, isheet, name);
                  if(col_index!=-1)
                  {
                        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;
                        }
                        EXCEL[iexcel].sheet[isheet].column[col_index].type=type;
                        width/=0xA;
                        if(width==0)
                              width=8;
                        EXCEL[iexcel].sheet[isheet].column[col_index].width=width;
                        fseek(f,LAYER+0x1E, SEEK_SET);
                        unsigned char c1,c2;
                        fread(&c1,1,1,f);
                        fread(&c2,1,1,f);
                        switch(c1)
                        {
                        case 0x00: // Numeric      - Dec1000
                        case 0x09: // Text&Numeric - Dec1000
                        case 0x10: // Numeric      - Scientific
                        case 0x19: // Text&Numeric - Scientific
                        case 0x20: // Numeric      - Engeneering
                        case 0x29: // Text&Numeric - Engeneering
                        case 0x30: // Numeric      - Dec1,000
                        case 0x39: // Text&Numeric - Dec1,000
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type=(c1%0x10==0x9)?6:0;
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type_specification=c1/0x10;
                              if(c2>=0x80)
                              {
                                    EXCEL[iexcel].sheet[isheet].column[col_index].significant_digits=c2-0x80;
                                    EXCEL[iexcel].sheet[isheet].column[col_index].numeric_display_type=2;
                              }
                              else if(c2>0)
                              {
                                    EXCEL[iexcel].sheet[isheet].column[col_index].decimal_places=c2-0x03;
                                    EXCEL[iexcel].sheet[isheet].column[col_index].numeric_display_type=1;
                              }
                              break;
                        case 0x02: // Time
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type=3;
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type_specification=c2-0x80;
                              break;
                        case 0x03: // Date
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type=2;
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type_specification=c2-0x80;
                              break;
                        case 0x31: // Text
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type=1;
                              break;
                        case 0x4: // Month
                        case 0x34:
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type=4;
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type_specification=c2;
                              break;
                        case 0x5: // Day
                        case 0x35:
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type=5;
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type_specification=c2;
                              break;
                        default: // Text
                              EXCEL[iexcel].sheet[isheet].column[col_index].value_type=1;
                              break;
                        }
                        fprintf(debug,"                     COLUMN \"%s\" type = %s(%d) (@ 0x%X)\n",
                              EXCEL[iexcel].sheet[isheet].column[col_index].name.c_str(),type,c,LAYER+0x11);
                        fflush(debug);
                  }
                  LAYER+=0x1E7+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  int comm_size=0;
                  fread(&comm_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(comm_size);
                  LAYER+=0x5;
                  if(comm_size>0)
                  {
                        char* comment=new char[comm_size+1];
                        comment[comm_size]='\0';
                        fseek(f,LAYER,SEEK_SET);
                        fread(comment,comm_size,1,f);
                        if(col_index!=-1)
                              EXCEL[iexcel].sheet[isheet].column[col_index].comment=comment;
                        LAYER+=comm_size+0x1;
                        delete comment;
                  }
                  fseek(f,LAYER,SEEK_SET);
                  int ntmp;
                  fread(&ntmp,4,1,f);
                  if(IsBigEndian()) SwapBytes(ntmp);
                  if(ntmp!=0x1E7)
                        break;
            }
            fprintf(debug,"         Done with excel %d\n", iexcel);
            fflush(debug);

            //POS = LAYER+0x5*0x6+0x1ED*0x12;
            LAYER+=0x5*0x5+0x1ED*0x12;
            fseek(f,LAYER,SEEK_SET);
            fread(&sec_size,4,1,f);
            if(IsBigEndian()) SwapBytes(sec_size);
            if(sec_size==0)
                  break;
            isheet++;
      }
      POS = LAYER+0x5;

      fseek(f,POS,SEEK_SET);
}

void OPJFile::readMatrixInfo(FILE *f, FILE *debug)
{
      int POS=ftell(f);

      int headersize;
      fread(&headersize,4,1,f);
      if(IsBigEndian()) SwapBytes(headersize);
      POS+=5;

      fprintf(debug,"               [Matrix SECTION (@ 0x%X)]\n",POS);
      fflush(debug);

      // check spreadsheet name
      char name[25];
      fseek(f,POS + 0x2,SEEK_SET);
      fread(&name,25,1,f);

      int idx=compareMatrixnames(name);
      MATRIX[idx].name=name;
      readWindowProperties(MATRIX[idx], f, debug, POS, headersize);

      unsigned char h = 0;
      fseek(f,POS+0x87,SEEK_SET);
      fread(&h,1,1,f);
      switch(h)
      {
      case 1:
            MATRIX[idx].view = matrix::ImageView;
            break;
      case 2:
            MATRIX[idx].header = matrix::XY;
            break;
      }

      int LAYER = POS;
      LAYER += headersize + 0x1;
      int sec_size;
      // LAYER section
      LAYER +=0x5;
      fseek(f,LAYER+0x2B,SEEK_SET);
      short w=0;
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);
      MATRIX[idx].nr_cols=w;
      fseek(f,LAYER+0x52,SEEK_SET);
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);
      MATRIX[idx].nr_rows=w;

      LAYER +=0x12D + 0x1;
      //now structure is next : section_header_size=0x6F(4 bytes) + '\n' + section_header(0x6F bytes) + section_body_1_size(4 bytes) + '\n' + section_body_1 + section_body_2_size(maybe=0)(4 bytes) + '\n' + section_body_2 + '\n'
      //possible sections: column formulas, __WIPR, __WIOTN, __LayerInfoStorage
      //section name(column name in formula case) starts with 0x46 position
      while(1)
      {
      //section_header_size=0x6F(4 bytes) + '\n'
            LAYER+=0x5;

      //section_header
            fseek(f,LAYER+0x46,SEEK_SET);
            char sec_name[42];
            sec_name[41]='\0';
            fread(&sec_name,41,1,f);

      //section_body_1_size
            LAYER+=0x6F+0x1;
            fseek(f,LAYER,SEEK_SET);
            fread(&sec_size,4,1,f);
            if(IsBigEndian()) SwapBytes(sec_size);

      //section_body_1
            LAYER+=0x5;
            //check if it is a formula
            if(0==strcmp(sec_name,"MV"))
            {
                  fseek(f,LAYER,SEEK_SET);
                  char *stmp=new char[sec_size+1];
                  stmp[sec_size]='\0';
                  fread(stmp,sec_size,1,f);
                  MATRIX[idx].command=stmp;
                  delete stmp;
            }

      //section_body_2_size
            LAYER+=sec_size+0x1;
            fseek(f,LAYER,SEEK_SET);
            fread(&sec_size,4,1,f);
            if(IsBigEndian()) SwapBytes(sec_size);

      //section_body_2
            LAYER+=0x5;

      //close section 00 00 00 00 0A
            LAYER+=sec_size+(sec_size>0?0x1:0)+0x5;

            if(0==strcmp(sec_name,"__LayerInfoStorage"))
                  break;

      }
      LAYER+=0x5;

      while(1)
      {
            LAYER+=0x5;

            short width=0;
            fseek(f,LAYER+0x2B, SEEK_SET);
            fread(&width,2,1,f);
            if(IsBigEndian()) SwapBytes(width);
            width=(width-55)/0xA;
            if(width==0)
                  width=8;
            MATRIX[idx].width=width;
            fseek(f,LAYER+0x1E, SEEK_SET);
            unsigned char c1,c2;
            fread(&c1,1,1,f);
            fread(&c2,1,1,f);

            MATRIX[idx].value_type_specification=c1/0x10;
            if(c2>=0x80)
            {
                  MATRIX[idx].significant_digits=c2-0x80;
                  MATRIX[idx].numeric_display_type=2;
            }
            else if(c2>0)
            {
                  MATRIX[idx].decimal_places=c2-0x03;
                  MATRIX[idx].numeric_display_type=1;
            }

            LAYER+=0x1E7+0x1;
            fseek(f,LAYER,SEEK_SET);
            int comm_size=0;
            fread(&comm_size,4,1,f);
            if(IsBigEndian()) SwapBytes(comm_size);
            LAYER+=0x5;
            if(comm_size>0)
            {
                  LAYER+=comm_size+0x1;
            }
            fseek(f,LAYER,SEEK_SET);
            int ntmp;
            fread(&ntmp,4,1,f);
            if(IsBigEndian()) SwapBytes(ntmp);
            if(ntmp!=0x1E7)
                  break;
      }

      LAYER+=0x5*0x5+0x1ED*0x12;
      POS = LAYER+0x5;

      fseek(f,POS,SEEK_SET);
}


void OPJFile::readGraphInfo(FILE *f, FILE *debug)
{
      int POS=ftell(f);

      int headersize;
      fread(&headersize,4,1,f);
      if(IsBigEndian()) SwapBytes(headersize);
      POS+=5;

      fprintf(debug,"               [Graph SECTION (@ 0x%X)]\n",POS);
      fflush(debug);

      char name[25];
      fseek(f,POS + 0x2,SEEK_SET);
      fread(&name,25,1,f);

      GRAPH.push_back(graph(name));
      readWindowProperties(GRAPH.back(), f, debug, POS, headersize);
      char c = 0;

      unsigned short graph_width;
      fseek(f,POS + 0x23,SEEK_SET);
      fread(&graph_width,2,1,f);
      if(IsBigEndian()) SwapBytes(graph_width);
      GRAPH.back().width = graph_width;

      unsigned short graph_height;
      fread(&graph_height,2,1,f);
      if(IsBigEndian()) SwapBytes(graph_height);
      GRAPH.back().height = graph_height;

      int LAYER = POS;
      LAYER += headersize + 0x1;
      int sec_size;
      while(1)// multilayer loop
      {
            GRAPH.back().layer.push_back(graphLayer());
            // LAYER section
            LAYER +=0x5;
            double range=0.0;
            unsigned char m=0;
            fseek(f, LAYER+0xF, SEEK_SET);
            fread(&range,8,1,f);
            if(IsBigEndian()) SwapBytes(range);
            GRAPH.back().layer.back().xAxis.min=range;
            fread(&range,8,1,f);
            if(IsBigEndian()) SwapBytes(range);
            GRAPH.back().layer.back().xAxis.max=range;
            fread(&range,8,1,f);
            if(IsBigEndian()) SwapBytes(range);
            GRAPH.back().layer.back().xAxis.step=range;
            fseek(f, LAYER+0x2B, SEEK_SET);
            fread(&m,1,1,f);
            GRAPH.back().layer.back().xAxis.majorTicks=m;
            fseek(f, LAYER+0x37, SEEK_SET);
            fread(&m,1,1,f);
            GRAPH.back().layer.back().xAxis.minorTicks=m;
            fread(&m,1,1,f);
            GRAPH.back().layer.back().xAxis.scale=m;

            fseek(f, LAYER+0x3A, SEEK_SET);
            fread(&range,8,1,f);
            if(IsBigEndian()) SwapBytes(range);
            GRAPH.back().layer.back().yAxis.min=range;
            fread(&range,8,1,f);
            if(IsBigEndian()) SwapBytes(range);
            GRAPH.back().layer.back().yAxis.max=range;
            fread(&range,8,1,f);
            if(IsBigEndian()) SwapBytes(range);
            GRAPH.back().layer.back().yAxis.step=range;
            fseek(f, LAYER+0x56, SEEK_SET);
            fread(&m,1,1,f);
            GRAPH.back().layer.back().yAxis.majorTicks=m;
            fseek(f, LAYER+0x62, SEEK_SET);
            fread(&m,1,1,f);
            GRAPH.back().layer.back().yAxis.minorTicks=m;
            fread(&m,1,1,f);
            GRAPH.back().layer.back().yAxis.scale=m;

            rect r;
            fseek(f, LAYER+0x71, SEEK_SET);
            fread(&r,sizeof(rect),1,f);
            if(IsBigEndian()) SwapBytes(r);
            GRAPH.back().layer.back().clientRect=r;

            LAYER += 0x12D + 0x1;
            //now structure is next : section_header_size=0x6F(4 bytes) + '\n' + section_header(0x6F bytes) + section_body_1_size(4 bytes) + '\n' + section_body_1 + section_body_2_size(maybe=0)(4 bytes) + '\n' + section_body_2 + '\n'
            //possible sections: axes, legend, __BC02, _202, _231, _232, __LayerInfoStorage etc
            //section name starts with 0x46 position
            while(1)
            {
            //section_header_size=0x6F(4 bytes) + '\n'
                  LAYER+=0x5;

            //section_header
                  fseek(f,LAYER+0x46,SEEK_SET);
                  char sec_name[42];
                  sec_name[41]='\0';
                  fread(&sec_name,41,1,f);

                  fseek(f, LAYER+0x3, SEEK_SET);
                  fread(&r,sizeof(rect),1,f);
                  if(IsBigEndian()) SwapBytes(r);

                  unsigned char attach=0;
                  fseek(f,LAYER+0x28,SEEK_SET);
                  fread(&attach,1,1,f);

                  unsigned char border=0;
                  fseek(f, LAYER+0x29, SEEK_SET);
                  fread(&border,1,1,f);

                  unsigned char color=0;
                  fseek(f,LAYER+0x33,SEEK_SET);
                  fread(&color,1,1,f);

            //section_body_1_size
                  LAYER+=0x6F+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_1
                  LAYER+=0x5;
                  int size=sec_size;

                  unsigned char type=0;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&type,1,1,f);

                  //text properties
                  short rotation=0;
                  fseek(f,LAYER+2,SEEK_SET);
                  fread(&rotation,2,1,f);
                  if(IsBigEndian()) SwapBytes(rotation);

                  unsigned char fontsize=0;
                  fread(&fontsize,1,1,f);

                  unsigned char tab=0;
                  fseek(f,LAYER+0xA,SEEK_SET);
                  fread(&tab,1,1,f);

                  //line properties
                  unsigned char line_style = 0;
                  double width = 0.0;
                  lineVertex begin, end;
                  unsigned int w = 0;

                  fseek(f,LAYER+0x12,SEEK_SET);
                  fread(&line_style,1,1,f);

                  fseek(f,LAYER+0x13,SEEK_SET);
                  fread(&w,2,1,f);
                  if(IsBigEndian()) SwapBytes(w);
                  width = (double)w/500.0;

                  fseek(f,LAYER+0x20,SEEK_SET);
                  fread(&begin.x,8,1,f);
                  if(IsBigEndian()) SwapBytes(begin.x);

                  fread(&end.x,8,1,f);
                  if(IsBigEndian()) SwapBytes(end.x);

                  fseek(f,LAYER+0x40,SEEK_SET);
                  fread(&begin.y,8,1,f);
                  if(IsBigEndian()) SwapBytes(begin.y);

                  fread(&end.y,8,1,f);
                  if(IsBigEndian()) SwapBytes(end.y);

                  fseek(f,LAYER+0x60,SEEK_SET);
                  fread(&begin.shape_type,1,1,f);

                  fseek(f,LAYER+0x64,SEEK_SET);
                  fread(&w,4,1,f);
                  if(IsBigEndian()) SwapBytes(w);
                  begin.shape_width = (double)w/500.0;

                  fread(&w,4,1,f);
                  if(IsBigEndian()) SwapBytes(w);
                  begin.shape_length = (double)w/500.0;

                  fseek(f,LAYER+0x6C,SEEK_SET);
                  fread(&end.shape_type,1,1,f);

                  fseek(f,LAYER+0x70,SEEK_SET);
                  fread(&w,4,1,f);
                  if(IsBigEndian()) SwapBytes(w);
                  end.shape_width = (double)w/500.0;

                  fread(&w,4,1,f);
                  if(IsBigEndian()) SwapBytes(w);
                  end.shape_length = (double)w/500.0;

                  // bitmap properties
                  short bitmap_width = 0;
                  fseek(f,LAYER+0x1,SEEK_SET);
                  fread(&bitmap_width,2,1,f);
                  if(IsBigEndian()) SwapBytes(bitmap_width);

                  short bitmap_height = 0;
                  fread(&bitmap_height,2,1,f);
                  if(IsBigEndian()) SwapBytes(bitmap_height);

                  double bitmap_left = 0.0;
                  fseek(f,LAYER+0x13,SEEK_SET);
                  fread(&bitmap_left,8,1,f);
                  if(IsBigEndian()) SwapBytes(bitmap_left);

                  double bitmap_top = 0.0;
                  fseek(f,LAYER+0x1B,SEEK_SET);
                  fread(&bitmap_top,8,1,f);
                  if(IsBigEndian()) SwapBytes(bitmap_top);

            //section_body_2_size
                  LAYER+=sec_size+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_2
                  LAYER+=0x5;
                  //check if it is a axis or legend
                  fseek(f,1,SEEK_CUR);
                  char stmp[255];
                  if(0==strcmp(sec_name,"XB"))
                  {
                        stmp[sec_size]='\0';
                        fread(&stmp,sec_size,1,f);
                        GRAPH.back().layer.back().xAxis.pos = Bottom;
                        GRAPH.back().layer.back().xAxis.label = text(stmp, r, color, fontsize, rotation/10, tab, (border >= 0x80 ? border-0x80 : None), attach);
                  }
                  else if(0==strcmp(sec_name,"XT"))
                  {
                        stmp[sec_size]='\0';
                        fread(&stmp,sec_size,1,f);
                        GRAPH.back().layer.back().xAxis.pos=Top;
                        GRAPH.back().layer.back().xAxis.label = text(stmp, r, color, fontsize, rotation/10, tab, (border >= 0x80 ? border-0x80 : None), attach);
                  }
                  else if(0==strcmp(sec_name,"YL"))
                  {
                        stmp[sec_size]='\0';
                        fread(&stmp,sec_size,1,f);
                        GRAPH.back().layer.back().yAxis.pos = Left;
                        GRAPH.back().layer.back().yAxis.label = text(stmp, r, color, fontsize, rotation/10, tab, (border >= 0x80 ? border-0x80 : None), attach);
                  }
                  else if(0==strcmp(sec_name,"YR"))
                  {
                        stmp[sec_size]='\0';
                        fread(&stmp,sec_size,1,f);
                        GRAPH.back().layer.back().yAxis.pos = Right;
                        GRAPH.back().layer.back().yAxis.label = text(stmp, r, color, fontsize, rotation/10, tab, (border >= 0x80 ? border-0x80 : None), attach);
                  }
                  else if(0==strcmp(sec_name,"Legend"))
                  {
                        stmp[sec_size]='\0';
                        fread(&stmp,sec_size,1,f);
                        GRAPH.back().layer.back().legend = text(stmp, r, color, fontsize, rotation/10, tab, (border >= 0x80 ? border-0x80 : None), attach);
                  }
                  else if(0==strcmp(sec_name,"__BCO2")) // histogram
                  {
                        double d;
                        fseek(f,LAYER+0x10,SEEK_SET);
                        fread(&d,8,1,f);
                        if(IsBigEndian()) SwapBytes(d);
                        GRAPH.back().layer.back().histogram_bin=d;
                        fseek(f,LAYER+0x20,SEEK_SET);
                        fread(&d,8,1,f);
                        if(IsBigEndian()) SwapBytes(d);
                        GRAPH.back().layer.back().histogram_end=d;
                        fseek(f,LAYER+0x28,SEEK_SET);
                        fread(&d,8,1,f);
                        if(IsBigEndian()) SwapBytes(d);
                        GRAPH.back().layer.back().histogram_begin=d;
                  }
                  else if(size==0x3E) // text
                  {
                        stmp[sec_size]='\0';
                        fread(&stmp,sec_size,1,f);
                        GRAPH.back().layer.back().texts.push_back(text(stmp));
                        GRAPH.back().layer.back().texts.back().color=color;
                        GRAPH.back().layer.back().texts.back().clientRect=r;
                        GRAPH.back().layer.back().texts.back().tab=tab;
                        GRAPH.back().layer.back().texts.back().fontsize=fontsize;
                        GRAPH.back().layer.back().texts.back().rotation=rotation/10;
                        GRAPH.back().layer.back().texts.back().attach=attach;
                        if(border>=0x80)
                              GRAPH.back().layer.back().texts.back().border_type=border-0x80;
                        else
                              GRAPH.back().layer.back().texts.back().border_type=None;
                  }
                  else if(size==0x78 && type==2) // line
                  {
                        GRAPH.back().layer.back().lines.push_back(line());
                        GRAPH.back().layer.back().lines.back().color=color;
                        GRAPH.back().layer.back().lines.back().clientRect=r;
                        GRAPH.back().layer.back().lines.back().attach=attach;
                        GRAPH.back().layer.back().lines.back().width=width;
                        GRAPH.back().layer.back().lines.back().line_style=line_style;
                        GRAPH.back().layer.back().lines.back().begin=begin;
                        GRAPH.back().layer.back().lines.back().end=end;
                  }
                  else if(size==0x28 && type==4) // bitmap
                  {
                        unsigned long filesize=sec_size+14;
                        GRAPH.back().layer.back().bitmaps.push_back(bitmap());
                        GRAPH.back().layer.back().bitmaps.back().left=bitmap_left;
                        GRAPH.back().layer.back().bitmaps.back().top=bitmap_top;
                        GRAPH.back().layer.back().bitmaps.back().width=
                              (GRAPH.back().layer.back().xAxis.max - GRAPH.back().layer.back().xAxis.min)*bitmap_width/10000;
                        GRAPH.back().layer.back().bitmaps.back().height=
                              (GRAPH.back().layer.back().yAxis.max - GRAPH.back().layer.back().yAxis.min)*bitmap_height/10000;
                        GRAPH.back().layer.back().bitmaps.back().attach=attach;
                        GRAPH.back().layer.back().bitmaps.back().size=filesize;
                        GRAPH.back().layer.back().bitmaps.back().data=new unsigned char[filesize];
                        unsigned char *data=GRAPH.back().layer.back().bitmaps.back().data;
                        //add Bitmap header
                        memcpy(data, "BM", 2);
                        data+=2;
                        memcpy(data, &filesize, 4);
                        data+=4;
                        unsigned int d=0;
                        memcpy(data, &d, 4);
                        data+=4;
                        d=0x36;
                        memcpy(data, &d, 4);
                        data+=4;
                        fread(data,sec_size,1,f);
                  }

            //close section 00 00 00 00 0A
                  LAYER+=sec_size+(sec_size>0?0x1:0);

            //section_body_3_size
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_3
                  LAYER+=0x5;

            //close section 00 00 00 00 0A
                  LAYER+=sec_size+(sec_size>0?0x1:0);

                  if(0==strcmp(sec_name,"__LayerInfoStorage"))
                        break;

            }
            LAYER+=0x5;
            unsigned char h;
            short w;

            fseek(f,LAYER,SEEK_SET);
            fread(&sec_size,4,1,f);
            if(IsBigEndian()) SwapBytes(sec_size);
            if(sec_size==0x1E7)//check layer is not empty
            {
                  while(1)
                  {
                        LAYER+=0x5;

                        graphCurve curve;

                        vector<string> col;
                        fseek(f,LAYER+0x4,SEEK_SET);
                        fread(&w,2,1,f);
                        if(IsBigEndian()) SwapBytes(w);
                        col=findDataByIndex(w-1);
                        short nColY = w;
                        if(col.size()>0)
                        {
                              fprintf(debug,"               GRAPH %d layer %d curve %d Y : %s.%s\n",GRAPH.size(),GRAPH.back().layer.size(),GRAPH.back().layer.back().curve.size(),col[1].c_str(),col[0].c_str());
                              fflush(debug);
                              curve.yColName=col[0];
                              curve.dataName=col[1];
                        }

                        fseek(f,LAYER+0x23,SEEK_SET);
                        fread(&w,2,1,f);
                        if(IsBigEndian()) SwapBytes(w);
                        col=findDataByIndex(w-1);
                        if(col.size()>0)
                        {
                              fprintf(debug,"               GRAPH %d layer %d curve %d X : %s.%s\n",GRAPH.size(),GRAPH.back().layer.size(),GRAPH.back().layer.back().curve.size(),col[1].c_str(),col[0].c_str());
                              fflush(debug);
                              curve.xColName=col[0];
                              if(curve.dataName!=col[1])
                                    fprintf(debug,"               GRAPH %d X and Y from different tables\n",GRAPH.size());
                        }

                        fseek(f,LAYER+0x4C,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.type=h;

                        fseek(f,LAYER+0x11,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.line_connect=h;

                        fseek(f,LAYER+0x12,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.line_style=h;

                        fseek(f,LAYER+0x15,SEEK_SET);
                        fread(&w,2,1,f);
                        if(IsBigEndian()) SwapBytes(w);
                        curve.line_width=(double)w/500.0;

                        fseek(f,LAYER+0x19,SEEK_SET);
                        fread(&w,2,1,f);
                        if(IsBigEndian()) SwapBytes(w);
                        curve.symbol_size=(double)w/500.0;

                        fseek(f,LAYER+0x1C,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea=(h==2?true:false);

                        fseek(f,LAYER+0x1E,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea_type=h;

                        //vector
                        if(curve.type == FlowVector || curve.type == Vector)
                        {
                              fseek(f,LAYER+0x56,SEEK_SET);
                              fread(&curve.vector.multiplier,4,1,f);
                              if(IsBigEndian()) SwapBytes(curve.vector.multiplier);

                              fseek(f,LAYER+0x5E,SEEK_SET);
                              fread(&h,1,1,f);
                              col=findDataByIndex(nColY - 1 + h - 0x64);
                              if(col.size()>0)
                              {
                                    curve.vector.endXColName = col[0];
                              }

                              fseek(f,LAYER+0x62,SEEK_SET);
                              fread(&h,1,1,f);
                              col=findDataByIndex(nColY - 1 + h - 0x64);
                              if(col.size()>0)
                              {
                                    curve.vector.endYColName = col[0];
                              }

                              fseek(f,LAYER+0x18,SEEK_SET);
                              fread(&h,1,1,f);
                              if(h >= 0x64)
                              {
                                    col=findDataByIndex(nColY - 1 + h - 0x64);
                                    if(col.size()>0)
                                          curve.vector.angleColName = col[0];
                              }
                              else if(h <= 0x08)
                              {
                                    curve.vector.const_angle = 45*h;
                              }

                              fseek(f,LAYER+0x19,SEEK_SET);
                              fread(&h,1,1,f);
                              if(h >= 0x64 && h < 0x1F4)
                              {
                                    col=findDataByIndex(nColY - 1 + h - 0x64);
                                    if(col.size()>0)
                                          curve.vector.magnitudeColName = col[0];
                              }
                              else
                              {
                                    curve.vector.const_magnitude = curve.symbol_size;
                              }

                              fseek(f,LAYER+0x66,SEEK_SET);
                              fread(&curve.vector.arrow_lenght,2,1,f);
                              if(IsBigEndian()) SwapBytes(curve.vector.arrow_lenght);

                              fread(&curve.vector.arrow_angle,1,1,f);

                              fread(&h,1,1,f);
                              curve.vector.arrow_closed = !(h&0x1);

                              fread(&w,2,1,f);
                              if(IsBigEndian()) SwapBytes(w);
                              curve.vector.width=(double)w/500.0;

                              fseek(f,LAYER+0x142,SEEK_SET);
                              fread(&h,1,1,f);
                              switch(h)
                              {
                              case 2:
                                    curve.vector.position = Midpoint;
                                    break;
                              case 4:
                                    curve.vector.position = Head;
                                  break;
                              default:
                                    curve.vector.position = Tail;
                                  break;
                              }
                              
                        }

                        //pie
                        if(curve.type == Pie)
                        {
                              fseek(f,LAYER+0x92,SEEK_SET);
                              fread(&h,1,1,f);
                              curve.pie.format_percentages = (h&0x01);
                              curve.pie.format_values = (h&0x02);
                              curve.pie.position_associate = (h&0x08);
                              curve.pie.clockwise_rotation = (h&0x20);
                              curve.pie.format_categories = (h&0x80);

                              fread(&h,1,1,f);
                              curve.pie.format_automatic = h;

                              fread(&curve.pie.distance,2,1,f);
                              if(IsBigEndian()) SwapBytes(curve.pie.distance);

                              fread(&curve.pie.view_angle,1,1,f);

                              fseek(f,LAYER+0x98,SEEK_SET);
                              fread(&curve.pie.thickness,1,1,f);

                              fseek(f,LAYER+0x9A,SEEK_SET);
                              fread(&curve.pie.rotation,2,1,f);
                              if(IsBigEndian()) SwapBytes(curve.pie.rotation);

                              fseek(f,LAYER+0x9E,SEEK_SET);
                              fread(&curve.pie.displacement,2,1,f);
                              if(IsBigEndian()) SwapBytes(curve.pie.displacement);

                              fseek(f,LAYER+0xA0,SEEK_SET);
                              fread(&curve.pie.radius,2,1,f);
                              if(IsBigEndian()) SwapBytes(curve.pie.radius);

                              fseek(f,LAYER+0xA2,SEEK_SET);
                              fread(&curve.pie.horizontal_offset,2,1,f);
                              if(IsBigEndian()) SwapBytes(curve.pie.horizontal_offset);

                              fseek(f,LAYER+0xA6,SEEK_SET);
                              fread(&curve.pie.displaced_sections,4,1,f);
                              if(IsBigEndian()) SwapBytes(curve.pie.displaced_sections);
                        }
                        
                        fseek(f,LAYER+0xC2,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea_color=h;

                        fseek(f,LAYER+0xC3,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea_first_color=h;

                        fseek(f,LAYER+0xCE,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea_pattern=h;

                        fseek(f,LAYER+0xCA,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea_pattern_color=h;

                        fseek(f,LAYER+0xC6,SEEK_SET);
                        fread(&w,2,1,f);
                        if(IsBigEndian()) SwapBytes(w);
                        curve.fillarea_pattern_width=(double)w/500.0;

                        fseek(f,LAYER+0xCF,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea_pattern_border_style=h;

                        fseek(f,LAYER+0xD2,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.fillarea_pattern_border_color=h;

                        fseek(f,LAYER+0xD0,SEEK_SET);
                        fread(&w,2,1,f);
                        if(IsBigEndian()) SwapBytes(w);
                        curve.fillarea_pattern_border_width=(double)w/500.0;

                        fseek(f,LAYER+0x16A,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.line_color=h;

                        fseek(f,LAYER+0x17,SEEK_SET);
                        fread(&w,2,1,f);
                        if(IsBigEndian()) SwapBytes(w);
                        curve.symbol_type=w;

                        fseek(f,LAYER+0x12E,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.symbol_fill_color=h;

                        fseek(f,LAYER+0x132,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.symbol_color=h;
                        curve.vector.color=h;

                        fseek(f,LAYER+0x136,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.symbol_thickness=(h==255?1:h);

                        fseek(f,LAYER+0x137,SEEK_SET);
                        fread(&h,1,1,f);
                        curve.point_offset=h;

                        GRAPH.back().layer.back().curve.push_back(curve);

                        LAYER+=0x1E7+0x1;
                        fseek(f,LAYER,SEEK_SET);
                        int comm_size=0;
                        fread(&comm_size,4,1,f);
                        if(IsBigEndian()) SwapBytes(comm_size);
                        LAYER+=0x5;
                        if(comm_size>0)
                        {
                              LAYER+=comm_size+0x1;
                        }
                        fseek(f,LAYER,SEEK_SET);
                        int ntmp;
                        fread(&ntmp,4,1,f);
                        if(IsBigEndian()) SwapBytes(ntmp);
                        if(ntmp!=0x1E7)
                              break;
                  }

            }
            //LAYER+=0x5*0x5+0x1ED*0x12;
            LAYER+=2*0x5;

            LAYER+=0x5;
            readGraphGridInfo(GRAPH.back().layer.back().xAxis.minorGrid, f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphGridInfo(GRAPH.back().layer.back().xAxis.majorGrid, f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisTickLabelsInfo(GRAPH.back().layer.back().xAxis.tickAxis[0], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisFormatInfo(GRAPH.back().layer.back().xAxis.formatAxis[0], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisTickLabelsInfo(GRAPH.back().layer.back().xAxis.tickAxis[1], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisFormatInfo(GRAPH.back().layer.back().xAxis.formatAxis[1], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;


            LAYER+=0x5;
            readGraphGridInfo(GRAPH.back().layer.back().yAxis.minorGrid, f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphGridInfo(GRAPH.back().layer.back().yAxis.majorGrid, f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisTickLabelsInfo(GRAPH.back().layer.back().yAxis.tickAxis[0], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisFormatInfo(GRAPH.back().layer.back().yAxis.formatAxis[0], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisTickLabelsInfo(GRAPH.back().layer.back().yAxis.tickAxis[1], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x5;
            readGraphAxisFormatInfo(GRAPH.back().layer.back().yAxis.formatAxis[1], f, LAYER);
            LAYER+=0x1E7+1;

            LAYER+=0x2*0x5+0x1ED*0x6;

            fseek(f,LAYER,SEEK_SET);
            fread(&sec_size,4,1,f);
            if(IsBigEndian()) SwapBytes(sec_size);
            if(sec_size==0)
                  break;
      }
      POS = LAYER+0x5;

      fseek(f,POS,SEEK_SET);
}

void OPJFile::skipObjectInfo(FILE *f, FILE *)
{
      int POS=ftell(f);

      int headersize;
      fread(&headersize,4,1,f);
      if(IsBigEndian()) SwapBytes(headersize);
      POS+=5;

      int LAYER = POS;
      LAYER += headersize + 0x1;
      int sec_size;
      while(1)// multilayer loop
      {
            // LAYER section
            LAYER +=0x5/* length of block = 0x12D + '\n'*/ + 0x12D + 0x1;
            //now structure is next : section_header_size=0x6F(4 bytes) + '\n' + section_header(0x6F bytes) + section_body_1_size(4 bytes) + '\n' + section_body_1 + section_body_2_size(maybe=0)(4 bytes) + '\n' + section_body_2 + '\n'
            //possible sections: column formulas, __WIPR, __WIOTN, __LayerInfoStorage
            //section name(column name in formula case) starts with 0x46 position
            while(1)
            {
            //section_header_size=0x6F(4 bytes) + '\n'
                  LAYER+=0x5;

            //section_header
                  fseek(f,LAYER+0x46,SEEK_SET);
                  char sec_name[42];
                  sec_name[41]='\0';
                  fread(&sec_name,41,1,f);

            //section_body_1_size
                  LAYER+=0x6F+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_1
                  LAYER+=0x5;

            //section_body_2_size
                  LAYER+=sec_size+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_2
                  LAYER+=0x5;

            //close section 00 00 00 00 0A
                  LAYER+=sec_size+(sec_size>0?0x1:0);

            //section_body_3_size
                  fseek(f,LAYER,SEEK_SET);
                  fread(&sec_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(sec_size);

            //section_body_3
                  LAYER+=0x5;

            //close section 00 00 00 00 0A
                  LAYER+=sec_size+(sec_size>0?0x1:0);

                  if(0==strcmp(sec_name,"__LayerInfoStorage"))
                        break;

            }
            LAYER+=0x5;

            while(1)
            {
                  LAYER+=0x5;

                  LAYER+=0x1E7+0x1;
                  fseek(f,LAYER,SEEK_SET);
                  int comm_size=0;
                  fread(&comm_size,4,1,f);
                  if(IsBigEndian()) SwapBytes(comm_size);
                  LAYER+=0x5;
                  if(comm_size>0)
                  {
                        LAYER+=comm_size+0x1;
                  }
                  fseek(f,LAYER,SEEK_SET);
                  int ntmp;
                  fread(&ntmp,4,1,f);
                  if(IsBigEndian()) SwapBytes(ntmp);
                  if(ntmp!=0x1E7)
                        break;
            }

            LAYER+=0x5*0x5+0x1ED*0x12;
            fseek(f,LAYER,SEEK_SET);
            fread(&sec_size,4,1,f);
            if(IsBigEndian()) SwapBytes(sec_size);
            if(sec_size==0)
                  break;
      }
      POS = LAYER+0x5;

      fseek(f,POS,SEEK_SET);
}

void OPJFile::readGraphGridInfo(graphGrid &grid, FILE *f, int pos)
{
      unsigned char h;
      short w;
      fseek(f,pos+0x26,SEEK_SET);
      fread(&h,1,1,f);
      grid.hidden=(h==0);

      fseek(f,pos+0xF,SEEK_SET);
      fread(&h,1,1,f);
      grid.color=h;


      fseek(f,pos+0x12,SEEK_SET);
      fread(&h,1,1,f);
      grid.style=h;

      fseek(f,pos+0x15,SEEK_SET);
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);
      grid.width=(double)w/500.0;
}

void OPJFile::readGraphAxisFormatInfo(graphAxisFormat &format, FILE *f, int pos)
{
      unsigned char h;
      short w;
      double p;
      fseek(f,pos+0x26,SEEK_SET);
      fread(&h,1,1,f);
      format.hidden=(h==0);

      fseek(f,pos+0xF,SEEK_SET);
      fread(&h,1,1,f);
      format.color=h;

      fseek(f,pos+0x4A,SEEK_SET);
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);
      format.majorTickLength=(double)w/10.0;

      fseek(f,pos+0x15,SEEK_SET);
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);
      format.thickness=(double)w/500.0;

      fseek(f,pos+0x25,SEEK_SET);
      fread(&h,1,1,f);
      format.minorTicksType=(h>>6);
      format.majorTicksType=((h>>4)&3);
      format.axisPosition=(h&0xF);
      switch(format.axisPosition)
      {
            case 1:
                  fseek(f,pos+0x37,SEEK_SET);
                  fread(&h,1,1,f);
                  format.axisPositionValue=(double)h;
                  break;
            case 2:
                  fseek(f,pos+0x2F,SEEK_SET);
                  fread(&p,8,1,f);
                  if(IsBigEndian()) SwapBytes(p);
                  format.axisPositionValue=p;
                  break;
      }
}

void OPJFile::readGraphAxisTickLabelsInfo(graphAxisTick &tick, FILE *f, int pos) {
      unsigned char h;
      unsigned char h1;
      short w;
      fseek(f,pos+0x26,SEEK_SET);
      fread(&h,1,1,f);
      tick.hidden=(h==0);

      fseek(f,pos+0xF,SEEK_SET);
      fread(&h,1,1,f);
      tick.color=h;

      fseek(f,pos+0x13,SEEK_SET);
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);
      tick.rotation=w/10;

      fseek(f,pos+0x15,SEEK_SET);
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);
      tick.fontsize=w;

      fseek(f,pos+0x1A,SEEK_SET);
      fread(&h,1,1,f);
      tick.fontbold=(h&0x8);

      fseek(f,pos+0x23,SEEK_SET);
      fread(&w,2,1,f);
      if(IsBigEndian()) SwapBytes(w);

      fseek(f,pos+0x25,SEEK_SET);
      fread(&h,1,1,f);
      fread(&h1,1,1,f);
      tick.value_type=(h&0xF);

      vector<string> col;
      switch(tick.value_type)
      {
      case 0: //Numeric

            /*switch((h>>4))
            {
                  case 0x9:
                        tick.value_type_specification=1;
                        break;
                  case 0xA:
                        tick.value_type_specification=2;
                        break;
                  case 0xB:
                        tick.value_type_specification=3;
                        break;
                  default:
                        tick.value_type_specification=0;
            }*/
            if((h>>4)>7)
            {
                  tick.value_type_specification=(h>>4)-8;
                  tick.decimal_places=h1-0x40;
            }
            else
            {
                  tick.value_type_specification=(h>>4);
                  tick.decimal_places=-1;
            }

            break;
      case 2: // Time
      case 3: // Date
      case 4: // Month
      case 5: // Day
      case 6: // Column heading
            tick.value_type_specification=h1-0x40;
            break;
      case 1: // Text
      case 7: // Tick-indexed dataset
      case 10: // Categorical
            col=findDataByIndex(w-1);
            if(col.size()>0)
            {
                  tick.colName=col[0];
                  tick.dataName=col[1];
            }
            break;
      default: // Numeric Decimal 1.000
            tick.value_type=Numeric;
            tick.value_type_specification=0;
            break;
      }
}

void OPJFile::readProjectTree(FILE *f, FILE *debug)
{
      readProjectTreeFolder(f, debug, projectTree.begin());

      fprintf(debug,"Origin project Tree\n");
      tree<projectNode>::iterator sib2=projectTree.begin(projectTree.begin());
    tree<projectNode>::iterator end2=projectTree.end(projectTree.begin());
    while(sib2!=end2)
      {
        for(int i=0; i<projectTree.depth(sib2)-1; ++i)
                  fprintf(debug," ");
            fprintf(debug,"%s\n",(*sib2).name.c_str());
        ++sib2;
    }
      fflush(debug);
}

void OPJFile::readProjectTreeFolder(FILE *f, FILE *debug, tree<projectNode>::iterator parent)
{
      int POS=ftell(f);

      POS+=5+0x20+1+5;
      fseek(f,POS,SEEK_SET);

      int namesize;
      fread(&namesize,4,1,f);
      if(IsBigEndian()) SwapBytes(namesize);

      POS+=5;

      // read folder name
      char* name=new char[namesize+1];
      name[namesize]='\0';
      fseek(f,POS,SEEK_SET);
      fread(name,namesize,1,f);
      tree<projectNode>::iterator current_folder=projectTree.append_child(parent, projectNode(name, 1));
      POS+=namesize+1+5+5;

      int objectcount;
      fseek(f,POS,SEEK_SET);
      fread(&objectcount,4,1,f);
      if(IsBigEndian()) SwapBytes(objectcount);
      POS+=5+5;

      for(int i=0; i<objectcount; ++i)
      {
            POS+=5;
            char c;
            fseek(f,POS+0x2,SEEK_SET);
            fread(&c,1,1,f);
            int objectID;
            fseek(f,POS+0x4,SEEK_SET);
            fread(&objectID,4,1,f);
            if(IsBigEndian()) SwapBytes(objectID);
            if(c==0x10)
            {
                  NOTE[objectID].parentFolder=current_folder->name;
                  projectTree.append_child(current_folder, projectNode(NOTE[objectID].name, 0));
            }
            else
                  projectTree.append_child(current_folder, projectNode(findObjectByIndex(objectID, current_folder->name), 0));
            POS+=8+1+5+5;
      }
      fseek(f,POS,SEEK_SET);
      fread(&objectcount,4,1,f);
      if(IsBigEndian()) SwapBytes(objectcount);
      fseek(f,1,SEEK_CUR);
      for(int i=0; i<objectcount; ++i)
            readProjectTreeFolder(f, debug, current_folder);
}

void OPJFile::readWindowProperties(originWindow& window, FILE *f, FILE *debug, int POS, int headersize)
{
      window.objectID=objectIndex;
      objectIndex++;

      fseek(f,POS + 0x1B,SEEK_SET);
      fread(&window.clientRect,8,1,f);
      if(IsBigEndian()) SwapBytes(window.clientRect);

      char c;
      fseek(f,POS + 0x32,SEEK_SET);
      fread(&c,1,1,f);

      if(c&0x01)
            window.state = originWindow::Minimized;
      else if(c&0x02)
            window.state = originWindow::Maximized;

      fseek(f,POS + 0x69,SEEK_SET);
      fread(&c,1,1,f);

      window.bHidden = (c&0x08);
      if(window.bHidden)
      {
            fprintf(debug,"               WINDOW %d NAME : %s     is hidden\n", objectIndex, window.name.c_str());
            fflush(debug);
      }
      
      if(headersize > 0xC3)
      {
            int labellen = 0;
            fseek(f,POS + 0xC3,SEEK_SET);
            fread(&c,1,1,f);
            while (c != '@')
            {
                  fread(&c,1,1,f);
                  labellen++;
            }
            if(labellen > 0)
            {
                  char *label=new char[labellen+1];
                  label[labellen]='\0';
                  fseek(f,POS + 0xC3,SEEK_SET);
                  fread(label,labellen,1,f);
                  window.label=label;
                  delete label;
            }
            else
                  window.label="";
            fprintf(debug,"               WINDOW %d LABEL: %s\n", objectIndex, window.label.c_str());
            fflush(debug);
      }
}
bool OPJFile::IsBigEndian()
{
   short word = 0x4321;
   if((*(char *)& word) != 0x21 )
     return true;
   else
     return false;
}

Generated by  Doxygen 1.6.0   Back to index