~ubuntu-branches/ubuntu/raring/mp3val/raring

« back to all changes in this revision

Viewing changes to mpegparse.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2008-01-23 09:11:35 UTC
  • mfrom: (3.1.3 hardy)
  • Revision ID: james.westby@ubuntu.com-20080123091135-r10vczs51d63e8p0
Tags: 0.1.7-3
* debian/control
  - bump Standards-Version to 3.7.3
  - bump dependency against debhelper to >=5
* debian/compat
  - bump to 5
* debian/dirs
  - removed since not needed
* debian/rules
  - do not ignore anymore clean error due to missing makefile
* debian/copyright
  - clear separation of upstream author, license and copyright
  - link to /usr/share/common-licenses/GPL file
* debian/mp3val.1
  - escaped minus signs (lintian warning)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * MP3val - a program for MPEG audio file validation
3
 
 * Copyright (C) 2005-2006 Alexey Kuznetsov (ring0) and Eugen Tikhonov (jetsys)
 
3
 * Copyright (C) 2005-2007 Alexey Kuznetsov (ring0) and Eugen Tikhonov (jetsys)
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
6
6
 * it under the terms of the GNU General Public License as published by
21
21
#include "mpegparse.h"
22
22
#include "report.h"
23
23
#include "out.h"
 
24
#include "crc.h"
24
25
#include <cstring>
25
26
#include <iostream>
26
27
#include <fstream>
34
35
int mpeg2layers23_bitrates[]={-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1};
35
36
 
36
37
int ValidateMPEGFrame(unsigned char *baseptr,int index, MPEGINFO *mpginfo);
 
38
int CheckMP3CRC(unsigned char *baseptr,int index,MPEGINFO *mpginfo,bool fix);
37
39
int ValidateID3v2Tag(unsigned char *baseptr,int index, MPEGINFO *mpginfo);
38
40
int ValidateAPEv2Tag(unsigned char *baseptr,int index, MPEGINFO *mpginfo);
39
41
 
48
50
 
49
51
int ValidateFile(unsigned char *baseptr,int iFileSize,MPEGINFO *mpginfo,ostream *out,char *filename,bool fix,int hFile) {
50
52
        int iFrame;
51
 
        int iFrameSize;
 
53
        int iFrameSize=0;
52
54
        int iLastMPEGFrame=0,iNewFrame;
53
55
        bool WasFirstFrame=false;
54
 
        int iXingOffset;
55
 
        int iID3v1Offset;
 
56
        int iXingOffset=0;
 
57
        int iID3v1Offset=0;
56
58
        int iFirstMPEGFrameOffset=0;
57
59
        DWORD dwTemp;
58
60
        int mpeg_total;
75
77
                else {
76
78
                        iFrame+=ValidateID3v2Tag(baseptr,iFrame,mpginfo);
77
79
                        if(fix) {
78
 
                                WriteToFile(hFile,(char *)baseptr,0,iFrame,iFileSize);
 
80
                                if(WriteToFile(hFile,(char *)baseptr,0,iFrame,iFileSize)==-1) return -1;
79
81
                                LastFrameWasMPEG=false;
80
82
                        }
81
83
                }
103
105
//MPEG frame
104
106
                        iFrameSize=ValidateMPEGFrame(baseptr,iFrame,mpginfo);
105
107
                        if(iFrameSize!=-1) {
 
108
                                if(iFrameSize+iFrame<=iFileSize&&mpginfo->iLastMPEGLayer==3&&mpginfo->bLastFrameCRC) CheckMP3CRC(baseptr,iFrame,mpginfo,fix);
106
109
                                if(fix&&!WasFirstFrame) iFirstMPEGFrameOffset=CrossAPI_SetFilePointer(hFile,0,true);
107
110
                                if(fix) {
108
 
                                        WriteToFile(hFile,(char *)baseptr,iFrame,iFrameSize,iFileSize);
 
111
                                        if(WriteToFile(hFile,(char *)baseptr,iFrame,iFrameSize,iFileSize)==-1) return -1;
109
112
                                        LastFrameWasMPEG=true;
110
113
                                }
111
114
                                if(!WasFirstFrame) {
134
137
                                continue;
135
138
                        }
136
139
                }
137
 
 
 
140
//APEv2 tag
138
141
                if(!memcmp(&baseptr[iFrame],"APET",4)) {
139
142
                        if(iFrame+16>iFileSize) {
140
143
                                mpginfo->truncated=iFrame;
142
145
                        }
143
146
                        iFrameSize=ValidateAPEv2Tag(baseptr,iFrame,mpginfo);
144
147
                        if(fix) {
145
 
                                WriteToFile(hFile,(char *)baseptr,iFrame,iFrameSize,iFileSize);
 
148
                                if(WriteToFile(hFile,(char *)baseptr,iFrame,iFrameSize,iFileSize)==-1) return -1;
146
149
                                LastFrameWasMPEG=false;
147
150
                        }
148
151
                        iFrame+=iFrameSize;
155
158
                                mpginfo->iTotalMPEGBytes-=WriteToFile(hFile,NULL,0,-1,-1);
156
159
                        }
157
160
                        else {
158
 
                                WriteToFile(hFile,NULL,0,-1,-1);
 
161
                                if(WriteToFile(hFile,NULL,0,-1,-1)==-1) return -1;
159
162
                        }
160
163
                }
161
164
                else if(LastFrameWasMPEG) {
203
206
        
204
207
        if(mpginfo->truncated>=0) {
205
208
                if(fix) {
206
 
                        WriteToFile(hFile,NULL,0,-1,-1);
 
209
                        if(WriteToFile(hFile,NULL,0,-1,-1)==-1) return -1;
207
210
                        if(LastFrameWasMPEG) {
208
211
                                mpginfo->iTotalMPEGBytes-=iFrameSize;
209
212
                                mpginfo->iDeletedFrames++;
215
218
                }
216
219
        }
217
220
 
218
 
        if(fix&&mpginfo->id3v1) WriteToFile(hFile,(char *)baseptr,iID3v1Offset,128,-1);
 
221
        if(fix&&mpginfo->id3v1) {
 
222
                if(WriteToFile(hFile,(char *)baseptr,iID3v1Offset,128,-1)==-1) return -1;
 
223
        }
219
224
 
220
225
        if(fix) CrossAPI_SetEndOfFile(hFile);
221
226
 
224
229
                        if(mpginfo->BytesPresent&&mpginfo->FramesPresent) {
225
230
                                CrossAPI_SetFilePointer(hFile,iFirstMPEGFrameOffset+iXingOffset+12,false);
226
231
                                dwTemp=rotate_dword(mpeg_total-mpginfo->iDeletedFrames);
227
 
                                WriteToFile(hFile,(char *)&dwTemp,0,4,-1);
 
232
                                if(WriteToFile(hFile,(char *)&dwTemp,0,4,-1)==-1) return -1;
228
233
                                dwTemp=rotate_dword(mpginfo->iTotalMPEGBytes);
229
 
                                WriteToFile(hFile,(char *)&dwTemp,0,4,-1);
 
234
                                if(WriteToFile(hFile,(char *)&dwTemp,0,4,-1)==-1) return -1;
230
235
                        }
231
236
                        else if(mpginfo->BytesPresent) {
232
237
                                CrossAPI_SetFilePointer(hFile,iFirstMPEGFrameOffset+iXingOffset+12,false);
233
238
                                dwTemp=rotate_dword(mpginfo->iTotalMPEGBytes);
234
 
                                WriteToFile(hFile,(char *)&dwTemp,0,4,-1);
 
239
                                if(WriteToFile(hFile,(char *)&dwTemp,0,4,-1)==-1) return -1;
235
240
                        }
236
241
                        else if(mpginfo->FramesPresent) {
237
242
                                CrossAPI_SetFilePointer(hFile,iFirstMPEGFrameOffset+iXingOffset+12,false);
238
243
                                dwTemp=rotate_dword(mpeg_total-mpginfo->iDeletedFrames);
239
 
                                WriteToFile(hFile,(char *)&dwTemp,0,4,-1);
 
244
                                if(WriteToFile(hFile,(char *)&dwTemp,0,4,-1)==-1) return -1;
240
245
                        }
241
246
                }
242
247
                else {
243
248
                        CrossAPI_SetFilePointer(hFile,iFirstMPEGFrameOffset+46,false);
244
249
                        dwTemp=rotate_dword(mpginfo->iTotalMPEGBytes);
245
 
                        WriteToFile(hFile,(char *)&dwTemp,0,4,-1);
 
250
                        if(WriteToFile(hFile,(char *)&dwTemp,0,4,-1)==-1) return -1;
246
251
                        dwTemp=rotate_dword(mpeg_total-mpginfo->iDeletedFrames);
247
 
                        WriteToFile(hFile,(char *)&dwTemp,0,4,-1);
 
252
                        if(WriteToFile(hFile,(char *)&dwTemp,0,4,-1)==-1) return -1;
248
253
                }
249
254
        }
250
255
 
251
256
        if(fix) mpginfo->iErrors=1;
252
257
 
253
258
        return 0;
254
 
 
255
259
}
256
260
 
257
261
int ValidateMPEGFrame(unsigned char *baseptr,int index, MPEGINFO *mpginfo) {
260
264
 
261
265
        int bitrate_index=0;
262
266
        int iFrameSize;
 
267
        
 
268
//Check if the frame contains CRC
 
269
        if(baseptr[index+1]&0x01) {
 
270
                mpginfo->bLastFrameCRC=false;
 
271
        }
 
272
        else {
 
273
                mpginfo->bLastFrameCRC=true;
 
274
                mpginfo->bCRC=true;
 
275
        }
263
276
 
264
277
// Determine MPEG version and layer
265
278
        switch((baseptr[index+1]>>1)&0x0F) {
338
351
                mpginfo->mpeg_stream_error=index;
339
352
                return -1;
340
353
        }
 
354
        
 
355
        if(mpginfo->iLastBitrate>0&&mpginfo->iLastBitrate!=mpeg_bitrate) mpginfo->bVariableBitrate=true;
 
356
        mpginfo->iLastBitrate=mpeg_bitrate;
341
357
 
342
358
//Determine sampling rate
343
359
        switch((baseptr[index+2]>>2)&0x03) {
382
398
        return iFrameSize;
383
399
}
384
400
 
 
401
int CheckMP3CRC(unsigned char *baseptr,int index,MPEGINFO *mpginfo,bool fix) {
 
402
        int crc=0xFFFF;
 
403
        int storedcrc=0;
 
404
        int iSideInfoSize;
 
405
        crc=CalculateCRC16(crc,0x8005,(char *)&baseptr[index+2],2);
 
406
        
 
407
        if(mpginfo->LastFrameStereo) {
 
408
                if(mpginfo->iLastMPEGVersion==1) {
 
409
                        iSideInfoSize=32;
 
410
                }
 
411
                else {
 
412
                        iSideInfoSize=17;
 
413
                }
 
414
        }
 
415
        else {
 
416
                if(mpginfo->iLastMPEGVersion==1) {
 
417
                        iSideInfoSize=17;
 
418
                }
 
419
                else {
 
420
                        iSideInfoSize=9;
 
421
                }
 
422
        }
 
423
        
 
424
        crc=CalculateCRC16(crc,0x8005,(char *)&baseptr[index+6],iSideInfoSize);
 
425
        
 
426
        ((char *)&storedcrc)[1]=baseptr[index+4];
 
427
        ((char *)&storedcrc)[0]=baseptr[index+5];
 
428
        
 
429
        if(storedcrc!=crc) {
 
430
                mpginfo->bCRCError=true;
 
431
                mpginfo->iCRCErrors++;
 
432
                if(fix) {
 
433
                        baseptr[index+4]=((char *)&crc)[1];
 
434
                        baseptr[index+5]=((char *)&crc)[0];
 
435
                }
 
436
        }
 
437
        
 
438
        return 0;
 
439
}
 
440
 
385
441
int ValidateID3v2Tag(unsigned char *baseptr,int index, MPEGINFO *mpginfo) {
386
442
        int iDataSize;
387
443