OggPage.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //===========================================================================
00031 
00032 #include "stdafx.h"
00033 #include <libOOOgg/OggPage.h>
00034 //LEACK CHECKED::: 20041018 - OK.
00035 
00036 
00037 // Checksum tables from libogg
00038 static unsigned long crc_lookup[256]={
00039   0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
00040   0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
00041   0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
00042   0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
00043   0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
00044   0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
00045   0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
00046   0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
00047   0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
00048   0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
00049   0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
00050   0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
00051   0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
00052   0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
00053   0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
00054   0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
00055   0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
00056   0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
00057   0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
00058   0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
00059   0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
00060   0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
00061   0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
00062   0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
00063   0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
00064   0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
00065   0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
00066   0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
00067   0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
00068   0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
00069   0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
00070   0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
00071   0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
00072   0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
00073   0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
00074   0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
00075   0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
00076   0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
00077   0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
00078   0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
00079   0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
00080   0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
00081   0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
00082   0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
00083   0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
00084   0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
00085   0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
00086   0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
00087   0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
00088   0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
00089   0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
00090   0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
00091   0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
00092   0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
00093   0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
00094   0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
00095   0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
00096   0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
00097   0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
00098   0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
00099   0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
00100   0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
00101   0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
00102   0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4
00103 };
00104 
00105 // End libogg tables
00106 
00107 
00108 OggPage::OggPage(void)
00109 {
00110         mHeader = new OggPageHeader;                    //Deleted in destructor.        
00111 }
00112 
00113 OggPage::~OggPage(void)
00114 {
00115         delete mHeader;
00116         for (unsigned long i = 0; i < mPacketList.size(); i++) {
00117                 delete mPacketList[i];
00118         }
00119 }
00120 
00121 //Retusn a view on the header only
00122 OggPageHeader* OggPage::header() {
00123         return mHeader;
00124 }
00125 
00126 //returns a view on the packet only.
00127 OggPacket* OggPage::getPacket(unsigned long inPacketNo) {
00128         if (inPacketNo < numPackets()) {
00129                 return mPacketList[inPacketNo];
00130         } else {
00131                 return NULL;
00132         }
00133 }
00134 //Returns a view on the packet only
00135 StampedOggPacket* OggPage::getStampedPacket(unsigned long inPacketNo) {
00136         if (inPacketNo < numPackets()) {
00137                 StampedOggPacket* retPacket = mPacketList[inPacketNo];
00138                 
00139                 if ((int)inPacketNo != ((int)numPackets() - (mPacketList[numPackets() - 1]->isTruncated() ? 2 : 1))) {
00140                         //It's not the last complete packet, so it gets a -1 stamp
00141                         retPacket->setTimeStamp(-1, -1, StampedOggPacket::OGG_END_ONLY);
00142                 } else {
00143                         //It is the last complete packet
00144                         
00145                         retPacket->setTimeStamp(-1, header()->GranulePos(), StampedOggPacket::OGG_END_ONLY);
00146                 }
00147                 return retPacket;
00148         } else {
00149                 return NULL;
00150         }
00151 }
00152 
00153 //Gives away  a pointer to the caller.
00154 OggPage* OggPage::clone() {
00155         OggPage* retClone = new OggPage;
00156         retClone->mHeader = mHeader->clone();
00157         for (size_t i = 0; i < mPacketList.size(); i++) {
00158                 retClone->mPacketList.push_back((StampedOggPacket*)mPacketList[i]->clone());            //The cloned new packet is deleted in the destructor
00159         }
00160         
00161         return retClone;
00162 }
00163 
00164 unsigned long OggPage::numPackets() {
00165         return (unsigned long)mPacketList.size();
00166 }
00167 
00168 //Gives a pointer to the caller, it must delete it.
00169 unsigned char* OggPage::createRawPageData() {
00170         unsigned char* locPage = new unsigned char[mHeader->pageSize()];                //Given to the caller
00171         mHeader->rawData(locPage, mHeader->pageSize());
00172 
00173         unsigned long locOffset = mHeader->headerSize();
00174         for (size_t i = 0; i < mPacketList.size(); i++) {
00175                 OggPacket* locPack = mPacketList[i];
00176                 memcpy((void*)(locPage + locOffset), (const void*)(locPack->packetData()), locPack->packetSize());
00177                 locOffset += locPack->packetSize();
00178         }
00179         return locPage;
00180 }
00181 
00182 bool OggPage::addPacket(StampedOggPacket* inPacket) {
00183         if (inPacket != NULL) {
00184                 mPacketList.push_back(inPacket);
00185                 return true;
00186         } else {
00187                 return false;
00188         }
00189 }
00190 
00191 /* n.b. This code is _duplicated_ in OggPaginator::setChecksum(), since I
00192    (andre) didn't want to risk unstabilising any existing code.  Zen, if feel
00193    like replacing OggPaginator::setChecksum() with an indirection to this,
00194    go for it. */
00195 void OggPage::computeAndSetCRCChecksum()
00196 {
00197         unsigned long locChecksum = 0;
00198         unsigned long locTemp = 0;
00199         unsigned char* locHeaderBuff = new unsigned char[300];
00200 
00201         // Set the checksum to NULL for the checksumming process.
00202         header()->setCRCChecksum((unsigned long)0);
00203         header()->rawData(locHeaderBuff, 300);
00204 
00205         for(unsigned long i = 0; i < headerSize(); i++) {
00206                 //Create the index we use for the lookup
00207                 locTemp = ((locChecksum >> 24) & 0xff) ^ locHeaderBuff[i];
00208                 //XOR the lookup value with the the current checksum shifted left 8 bits.
00209                 locChecksum=(locChecksum << 8) ^ crc_lookup[locTemp];
00210         }
00211 
00212         unsigned char* locBuff = NULL;
00213         for(unsigned long i = 0; i < numPackets(); i++) {
00214                 locBuff = getPacket(i)->packetData();                   //View only don't delete.
00215 
00216                 for (unsigned long j = 0; j < getPacket(i)->packetSize(); j++) {
00217                         locTemp = ((locChecksum >> 24) & 0xff) ^ locBuff[j];
00218             locChecksum = (locChecksum << 8) ^ crc_lookup[locTemp];
00219                 }
00220         }
00221 
00222         header()->setCRCChecksum(locChecksum);
00223 }
00224 
00225 
00226 unsigned long OggPage::pageSize()
00227 {
00228         return mHeader->pageSize();
00229 }
00230 unsigned long OggPage::headerSize()
00231 {
00232         return mHeader->headerSize();
00233 }
00234 unsigned long OggPage::dataSize()
00235 {
00236         return mHeader->dataSize();
00237 }

Generated on Thu Feb 16 23:48:16 2006 for oggdsf by  doxygen 1.3.9