12 #include "stringptr.h"
17 unsigned int filesize_minus_8
;
20 unsigned int formatheadersize
;
21 unsigned short format
;
22 unsigned short channels
;
23 unsigned int samplerate
;
24 unsigned int bytespersec
;
25 unsigned short blockalign
;
26 unsigned short bitwidth
;
29 size_t getfilesize(char *filename
) {
31 if(!stat(filename
, &st
)) {
37 stringptr
*readfile(char *filename
) {
40 size_t size
= getfilesize(filename
);
45 f
= fopen(filename
, "r");
49 buf
= new_string(size
);
54 while(bufpos
< size
) {
55 bread
= fread(buf
->ptr
+ bufpos
, 1, 64 * 1024, f
);
58 printf(strerror(errno
));
67 void searchBiggestRepeatingBlock(stringptr
* buf
) {
68 size_t samplesize
= 8;
71 size_t lastfoundoffset
= 0;
72 size_t lastfoundsamplesize
= 0;
74 while(startpos
< buf
->size
- samplesize
) {
75 printf("approaching startpos %d with samplesize %d\n", startpos
, samplesize
);
76 scanpos
= startpos
+ samplesize
;
77 while(scanpos
< buf
->size
- samplesize
) {
78 if(buf
->ptr
[startpos
] == buf
->ptr
[scanpos
] &&
79 buf
->ptr
[startpos
+ samplesize
- 1] == buf
->ptr
[scanpos
+ samplesize
- 1] &&
80 memcmp(buf
->ptr
+ startpos
, buf
->ptr
+ scanpos
, samplesize
) == 0) {
81 lastfoundoffset
= scanpos
;
82 lastfoundsamplesize
= samplesize
;
84 while(scanpos
+ samplesize
< buf
->size
85 && buf
->ptr
[startpos
+ samplesize
- 1] == buf
->ptr
[scanpos
+ samplesize
- 1])
95 printf("\nlastfoundoffset: %d, lastfoundsamplesize: %d\n", lastfoundoffset
, lastfoundsamplesize
);
99 void searchLoop(char *buf
, size_t bufsize
, size_t startpos
, size_t minsize
, size_t blocksize
) {
100 size_t samplesize
= minsize
;
104 //align startpos to blocksize
105 startpos
+= startpos
% blocksize
;
107 while(startpos
< bufsize
- samplesize
) {
108 if(startpos
% 1000 == 0)
109 printf("approaching startpos %d with samplesize %d\n", startpos
, samplesize
);
110 assert(startpos
% blocksize
== 0);
111 samplesize
= minsize
;
112 scanpos
= startpos
+ minsize
;
114 //scanning the buffer from scanpos till eof, comparing with the junk from startpos.
115 while(scanpos
< bufsize
- samplesize
) {
116 if(!memcmp(buf
+ startpos
, buf
+ scanpos
, samplesize
)) {
117 while(scanpos
+ samplesize
< bufsize
&& startpos
+ samplesize
< scanpos
118 && !memcmp(buf
+ startpos
+ samplesize
, buf
+ scanpos
+ samplesize
, blocksize
))
119 samplesize
+= blocksize
;
120 if(startpos
+ samplesize
== scanpos
|| scanpos
+ samplesize
== bufsize
) {
121 printf("(possible) loop found at offset %d, length %d, repeats at %d!\n",
122 startpos
, samplesize
, scanpos
);
123 // lets search for a bigger loop, which includes everything here
128 printf("match of length %d found at %d and %d\n", samplesize
, startpos
,
131 samplesize
= scanpos
- startpos
;
135 scanpos
+= blocksize
;
140 startpos
+= blocksize
;
142 printf("no loops found :-/\n");
145 int checkWaveValid(WAVE_HEADER
* wave
) {
146 if(!memcmp((char *) wave
->text_RIFF
, "RIFF", 4) &&
147 !memcmp((char *) wave
->text_WAVE
, "WAVE", 4) &&
148 !memcmp((char *) wave
->text_fmt
, "fmt ", 4) && !memcmp((char *) &wave
->format
, "\x01\x00", 2))
154 size_t findWaveDataStart(WAVE_HEADER
* wave
) {
155 if(checkWaveValid(wave
)) {
157 ((char *) &wave
->formatheadersize
+ sizeof(wave
->formatheadersize
) + wave
->formatheadersize
, "data",
159 return ((size_t) & wave
->formatheadersize
- (size_t) wave
) + sizeof(wave
->formatheadersize
) +
160 wave
->formatheadersize
+ sizeof(int);
165 int main(int argc
, char **argv
) {
166 // gcc -Wall -g -Isource loopfinder.c source/stringptr.c -o loopfinder
169 WAVE_HEADER
*wave
= NULL
;
174 puts("need a valid filename as argv1, scanstartoffset as argv2, minimum matchsize in bytes as argv3");
178 buf
= readfile(argv
[1]);
179 startpos
= atoi(argv
[2]);
180 minsize
= atoi(argv
[3]);
181 if(buf
->size
> sizeof(WAVE_HEADER
)) {
182 wave
= (WAVE_HEADER
*) buf
->ptr
;
183 data
= buf
->ptr
+ findWaveDataStart(wave
);
184 datasize
= buf
->size
- ((size_t) data
- (size_t) buf
->ptr
);
186 printf("no valid WAVE file or compressed format. scanning whole file.\n");
188 printf("skipping WAVE header of length %d\n", (size_t) data
- (size_t) buf
->ptr
);
191 if(wave
&& datasize
% wave
->blockalign
!= 0) {
192 printf("error, filesize doesnt match blockalign!");
196 searchLoop(data
, datasize
, startpos
, minsize
, wave
? wave
->blockalign
: 1);