home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Multimedia / xcd / core / xcd_media_reader.h < prev   
C/C++ Source or Header  |  2002-07-14  |  7KB  |  191 lines

  1. /*************************************************************************
  2. XCD reader class
  3. (currently supports only single mode2 form2 file without error corrections)
  4.  
  5. Written by Avi Halachmi (avih [avihpit@yahoo.com])
  6. **************************************************************************
  7. */
  8.  
  9.  
  10. #ifndef _XCD_MEDIA_READER_H_
  11. #define _XCD_MEDIA_READER_H_
  12.  
  13. #include "portab.h"
  14. #include "utils.h"
  15.  
  16. #define DEFAULT_BUFFER_SIZE_KB 1000
  17.  
  18. //This class is able to produce a single media stream out of one or two related XCD files.
  19. // current implementation supports single m2f2 file only.
  20.  
  21. class XCD_Media_Reader{
  22. public:
  23.     XCD_Media_Reader(const char* baseFileName, int forceNoSkipEmptySectors=0, int bufferSizeKB=DEFAULT_BUFFER_SIZE_KB);
  24.     int isOpenedOK();
  25.     long size(){return m_mediaSize;};
  26.     long read(void* dest, long mediaPosition, long size);
  27.     ~XCD_Media_Reader();
  28.  
  29.     
  30.     long readNext(void* dest, long size){return read(dest, m_mediaPosition, size);};    
  31.     long readNonStripped(void* dest, long position, long size);    // for direct access to the file as seen by the OS.
  32.  
  33. //    int isSVCD();
  34. //    int isVCD();
  35. //    char* getMediaFileName();
  36.  
  37. private:
  38.     void        init(int virtualHeaderSizeByOS=RIFF_SIZE);
  39.     long        m_posFirstSectorInFile;
  40.     long        m_posFirstMediaSectorInFile;
  41.     int            m_forceNoSkipEmptySectors;
  42.     FILE*        m_m2f1MediaHandle;    //header file, should contain auxilary media data
  43.     FILE*        m_m2f2MediaHandle;    //the unprotected media stream itself (if some of the file is unprotected)
  44.     char        m_sectorBuffer[SECTOR_SIZE];
  45.     long        m_m2f2FileSize;
  46.     long        m_mediaSize;
  47.     long        m_mediaPosition;
  48. };
  49.  
  50.  
  51.  
  52. #define MAX_EMPTY_SECTORS 1000
  53.  
  54.  
  55. XCD_Media_Reader::XCD_Media_Reader(const char* baseFileName, int forceNoSkipEmptySectors, int bufferSizeKB){
  56.     m_posFirstSectorInFile=m_posFirstMediaSectorInFile=m_forceNoSkipEmptySectors=m_m2f2FileSize=m_mediaSize=-1;
  57.     m_mediaPosition=-1;
  58.     m_m2f1MediaHandle=m_m2f2MediaHandle=NULL;
  59.  
  60.     m_m2f2MediaHandle=fopen(baseFileName,"rb");
  61.     m_forceNoSkipEmptySectors=forceNoSkipEmptySectors;
  62.     
  63.     //currently only m2f2 file is supported.
  64.  
  65.     init();    //default value for init is 44 bytes added by windows as a RIFF header.
  66. //    init(0);// use in OSs that don't add virtual headers
  67. }
  68.  
  69.  
  70. long XCD_Media_Reader::readNonStripped(void* dest, long position, long size){    // for direct access to the file as seen via the OS.
  71.     //should 'overlay' backups when implemented.
  72.     if (fseek(m_m2f2MediaHandle, position, SEEK_SET)){//unsuccessfull seek
  73.         dprintf ("fseek(%d) NO success\n",position);
  74.         return 0;
  75.     }
  76.     
  77.     long result=fread(dest, 1, size, m_m2f2MediaHandle);
  78.     dprintf ("fread(pos=%d, size=%d)=%d\n",position, size,result);
  79.     return result;
  80. }
  81.  
  82.  
  83. void XCD_Media_Reader::init(int virtualHeaderSizeByOS){
  84.     int i, bytesRead;
  85.     m_posFirstSectorInFile=virtualHeaderSizeByOS;
  86.     
  87.     if (!m_forceNoSkipEmptySectors){
  88.         //try to find leading empty sectors. currently to cope with S/VCD (identified by subheader)
  89.         for (i=0; i<MAX_EMPTY_SECTORS; i++){
  90.             if (bytesRead=readSector(m_m2f2MediaHandle, m_posFirstSectorInFile, m_sectorBuffer, i)==SECTOR_SIZE){
  91.                 if (!isEmptySector(m_sectorBuffer)){
  92.                     m_posFirstMediaSectorInFile=m_posFirstSectorInFile+i*SECTOR_SIZE;
  93.                     dprintf ("XCD_Media_Reader::init, sector#%d: Non-Empty\n", i);
  94.                     break;
  95.                 } else {
  96.                     dprintf ("XCD_Media_Reader::init, sector#%d: Empty\n", i);
  97.                 }
  98.             } else {
  99.                 if (bytesRead<0)
  100.                     dprintf ("XCD_Media_Reader::init, sector#%d: read ERROR\n", i);
  101.                 else
  102.                     dprintf ("XCD_Media_Reader::init, sector#%d: read %d bytes\n", i, bytesRead);
  103.             }
  104.         }
  105.  
  106.         if (i>=MAX_EMPTY_SECTORS){    // didn't find non-empty sector. fallback to read all sectors (->assumming isEmptySector doesn't work properly).
  107.             dprintf ("Too many 'empty' sectors... fallback to 'forceNoSkipEmpty'\n");
  108.             m_posFirstMediaSectorInFile=m_posFirstSectorInFile;
  109.         }
  110.     } else {
  111.         dprintf("forced no skip empty sectors. skipped empty sectors detection.");
  112.     }
  113.  
  114.     dprintf ("XCD_Media_Reader::init, m_posFirstMediaSectorInFile=%d\n", m_posFirstMediaSectorInFile);
  115.  
  116.     dprintf ("before fsize()\n");
  117.     m_m2f2FileSize=fsize(m_m2f2MediaHandle);
  118.     m_mediaSize=mediaPosition(m_m2f2FileSize, m_posFirstMediaSectorInFile);
  119.  
  120.     dprintf ("XCD_Media_Reader::init, m2f2FileSize=%d, mediaSize=%d\n",m_m2f2FileSize, m_mediaSize);
  121. }
  122.  
  123.  
  124. int XCD_Media_Reader::isOpenedOK(){
  125.     // should modify to test also m2f1 file when implemented.
  126.     return (m_m2f2MediaHandle!=NULL);
  127. }
  128.  
  129. //return value is number of bytes actually read.
  130. long XCD_Media_Reader::read(void* dest, long mediaPosition, long size){
  131.     long origSize=size;
  132.  
  133.     m_mediaPosition=mediaPosition =min( max(mediaPosition, 0), m_mediaSize);
  134.     size =min( max(size, 0), m_mediaSize-mediaPosition);
  135.     long actualSize=size;
  136.  
  137.     long actualStart=filePosition(mediaPosition, m_posFirstMediaSectorInFile);
  138.  
  139.     dprintf ("XCD_Media_Reader::read, mediaPos=%d, size=%d, actualSize=%d, actualStart=%d\n",
  140.                    mediaPosition, origSize, size, actualStart);
  141. //    dprintf ("XCD_Media_Reader::read, actualStart=%d\n",actualStart);
  142.  
  143.     long startForPrintf=actualStart;
  144.  
  145.     if (size<= (SECTOR_USER_DATA - mediaPosition%SECTOR_USER_DATA)){    // inside single USER_DATA block
  146.         readNonStripped(dest, actualStart, (uint32_t)size);
  147.     } else {    //extends over more than single USER_DATA block
  148.         long firstLength=SECTOR_USER_DATA - mediaPosition%SECTOR_USER_DATA;
  149.         readNonStripped(dest, actualStart, (DWORD)firstLength);
  150.         size-=firstLength;
  151.         dest=(char*)dest+firstLength;
  152.  
  153.         actualStart+=firstLength+SECTOR_EDC+SECTOR_HEADERS;//points to the start of next USER_DATA block
  154.         while (size>0){
  155.             if (size<=SECTOR_USER_DATA){    // last copy, smaller or equal to USER_DATA size.
  156.                 readNonStripped(dest, actualStart, (DWORD)size);
  157.                 break;
  158.             } else {
  159.                 readNonStripped(dest, actualStart, SECTOR_USER_DATA);
  160.                 size-=SECTOR_USER_DATA;
  161.                 dest=(char*)dest+SECTOR_USER_DATA;
  162.                 actualStart+=SECTOR_SIZE;
  163.             }
  164.         }
  165.     }
  166.     dprintf ("ActualStart(%d)=%d, returning %d",(long)mediaPosition, (long)startForPrintf, actualSize);
  167.     m_mediaPosition+=actualSize;
  168.     return actualSize;    //should we change that in case we didn't read origSize??
  169. }
  170.  
  171.  
  172. XCD_Media_Reader::~XCD_Media_Reader(){
  173.     if (m_m2f1MediaHandle){
  174.         if (fclose(m_m2f1MediaHandle))
  175.             dprintf ("XCD_Media_Reader::~XCD_Media_Reader, Error closing m2f1 media\n");
  176.         else
  177.             dprintf ("XCD_Media_Reader::~XCD_Media_Reader, closed m2f1 media\n");
  178.     } else
  179.         dprintf ("XCD_Media_Reader::~XCD_Media_Reader, m2f1 media was not open. not closing\n");
  180.  
  181.     if (m_m2f2MediaHandle){
  182.         if (fclose(m_m2f2MediaHandle))
  183.             dprintf ("XCD_Media_Reader::~XCD_Media_Reader, Error closing m2f2 media\n");
  184.         else
  185.             dprintf ("XCD_Media_Reader::~XCD_Media_Reader, closed m2f2 media\n");
  186.     } else
  187.         dprintf ("XCD_Media_Reader::~XCD_Media_Reader, m2f2 media was not open. not closing\n");
  188. }
  189.  
  190. #endif
  191.