Rev 7 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7 | Rev 8 | ||
---|---|---|---|
Line 271... | Line 271... | ||
271 | PAVIFILE pFile; |
271 | PAVIFILE pFile; |
272 | int res; |
272 | int res; |
273 | PAVISTREAM pStream1; |
273 | PAVISTREAM pStream1; |
274 | AVISTREAMINFOA asi1; |
274 | AVISTREAMINFOA asi1; |
275 | 275 | ||
276 | if (!CreateDirectoryA(outdir, NULL)) { |
- | |
277 | // Also happens if the directory already exists... |
276 | // Try creating the directory |
278 | //printf("ERROR: Could not create directory %s\n", outdir); |
- | |
279 | //return false; |
277 | CreateDirectoryA(outdir, NULL); |
280 | } |
- | |
281 | 278 | ||
282 | if (!dirExists(outdir)) { |
279 | if (!dirExists(outdir)) { |
283 | fprintf(stderr, "ERROR: Directory couldn't be created! %s\n", outdir); |
280 | fprintf(stderr, "ERROR: Directory couldn't be created! %s\n", outdir); |
284 | return 1; |
281 | return 1; |
285 | } |
282 | } |
286 | 283 | ||
287 | res = AVIFileOpenA(&pFile, filename, OF_SHARE_DENY_WRITE, 0L); |
284 | res = AVIFileOpenA(&pFile, filename, OF_SHARE_DENY_WRITE, 0L); |
288 | if (res == AVIERR_FILEOPEN) { |
285 | if (res == AVIERR_FILEOPEN) { |
289 | printf("ERROR: AVIFileOpenA(%s) returns AVIERR_FILEOPEN. Does the file exist?\n", filename); |
286 | fprintf(stderr, "ERROR: AVIFileOpenA(%s) returns AVIERR_FILEOPEN. Does the file exist?\n", filename); |
290 | return false; |
287 | return false; |
291 | } |
288 | } |
292 | if (res != 0) { |
289 | if (res != 0) { |
293 | printf("ERROR: AVIFileOpenA(%s) returns %d\n", filename, res); |
290 | fprintf(stderr, "ERROR: AVIFileOpenA(%s) returns %d\n", filename, res); |
294 | return false; |
291 | return false; |
295 | } |
292 | } |
296 | 293 | ||
297 | res = AVIFileGetStream(pFile, &pStream1, streamtypeVIDEO, 0); |
294 | res = AVIFileGetStream(pFile, &pStream1, streamtypeVIDEO, 0); |
298 | if (res == AVIERR_NODATA) { |
295 | if (res == AVIERR_NODATA) { |
299 | printf("ERROR: AVIFileGetStream returns AVIERR_NODATA\n"); |
296 | fprintf(stderr, "ERROR: AVIFileGetStream returns AVIERR_NODATA\n"); |
300 | AVIFileRelease(pFile); |
297 | AVIFileRelease(pFile); |
301 | return false; |
298 | return false; |
302 | } |
299 | } |
303 | if (res == AVIERR_MEMORY) { |
300 | if (res == AVIERR_MEMORY) { |
304 | printf("ERROR: AVIFileGetStream returns AVIERR_MEMORY\n"); |
301 | fprintf(stderr, "ERROR: AVIFileGetStream returns AVIERR_MEMORY\n"); |
305 | AVIFileRelease(pFile); |
302 | AVIFileRelease(pFile); |
306 | return false; |
303 | return false; |
307 | } |
304 | } |
308 | if (res != 0) { |
305 | if (res != 0) { |
309 | printf("ERROR: AVIFileGetStream returns %d\n", res); |
306 | fprintf(stderr, "ERROR: AVIFileGetStream returns %d\n", res); |
310 | AVIFileRelease(pFile); |
307 | AVIFileRelease(pFile); |
311 | return false; |
308 | return false; |
312 | } |
309 | } |
313 | 310 | ||
314 | 311 | ||
315 | res = AVIStreamInfoA(pStream1, &asi1, sizeof(asi1)); |
312 | res = AVIStreamInfoA(pStream1, &asi1, sizeof(asi1)); |
316 | if (res != 0) { |
313 | if (res != 0) { |
317 | printf("ERROR: AVIStreamInfoA returns %d\n", res); |
314 | fprintf(stderr, "ERROR: AVIStreamInfoA returns %d\n", res); |
318 | AVIStreamRelease(pStream1); |
315 | AVIStreamRelease(pStream1); |
319 | AVIFileRelease(pFile); |
316 | AVIFileRelease(pFile); |
320 | return false; |
317 | return false; |
321 | } |
318 | } |
322 | 319 | ||
Line 341... | Line 338... | ||
341 | { |
338 | { |
342 | ipmaVersion = 2; |
339 | ipmaVersion = 2; |
343 | } |
340 | } |
344 | 341 | ||
345 | if (ipmaVersion == 0) { |
342 | if (ipmaVersion == 0) { |
346 | printf("ERROR: Not an IPMA or IP20 AVI file!\n"); |
343 | fprintf(stderr, "ERROR: Not an IPMA or IP20 AVI file!\n"); |
347 | AVIStreamRelease(pStream1); |
344 | AVIStreamRelease(pStream1); |
348 | AVIFileRelease(pFile); |
345 | AVIFileRelease(pFile); |
349 | return false; |
346 | return false; |
350 | } |
347 | } |
351 | 348 | ||
Line 358... | Line 355... | ||
358 | ZeroMemory(pstrf, strf_siz); |
355 | ZeroMemory(pstrf, strf_siz); |
359 | 356 | ||
360 | //res = pStream1->ReadFormat(i, (LPVOID)pstrf, &strf_siz); |
357 | //res = pStream1->ReadFormat(i, (LPVOID)pstrf, &strf_siz); |
361 | res = AVIStreamReadFormat(pStream1, i, (LPVOID)pstrf, &strf_siz); |
358 | res = AVIStreamReadFormat(pStream1, i, (LPVOID)pstrf, &strf_siz); |
362 | if (res != 0) { |
359 | if (res != 0) { |
363 | printf("ERROR: Read format info failed\n"); |
360 | fprintf(stderr, "ERROR: Read format info failed\n"); |
364 | AVIStreamRelease(pStream1); |
361 | AVIStreamRelease(pStream1); |
365 | AVIFileRelease(pFile); |
362 | AVIFileRelease(pFile); |
366 | return false; |
363 | return false; |
367 | } |
364 | } |
368 | 365 | ||
369 | 366 | ||
370 | if (((ipmaVersion == 1) && (asi1.fccHandler != mmioFOURCC('I', 'p', 'm', 'a'))) && |
367 | if (((ipmaVersion == 1) && (asi1.fccHandler != mmioFOURCC('I', 'p', 'm', 'a'))) && |
371 | ((ipmaVersion == 2) && (asi1.fccHandler != mmioFOURCC('I', 'p', '2', '0')))) |
368 | ((ipmaVersion == 2) && (asi1.fccHandler != mmioFOURCC('I', 'p', '2', '0')))) |
372 | { |
369 | { |
373 | // biCompression is case-sensitive and must be "Ipma" or "Ip20" |
370 | // biCompression is case-sensitive and must be "Ipma" or "Ip20" |
374 | if (ipmaVersion == 1) printf("ERROR: biCompression is not Ipma!\n"); |
371 | if (ipmaVersion == 1) fprintf(stderr, "ERROR: biCompression is not Ipma!\n"); |
375 | if (ipmaVersion == 2) printf("ERROR: biCompression is not Ip20!\n"); |
372 | if (ipmaVersion == 2) fprintf(stderr, "ERROR: biCompression is not Ip20!\n"); |
376 | AVIStreamRelease(pStream1); |
373 | AVIStreamRelease(pStream1); |
377 | AVIFileRelease(pFile); |
374 | AVIFileRelease(pFile); |
378 | return false; |
375 | return false; |
379 | } |
376 | } |
380 | 377 | ||
Line 397... | Line 394... | ||
397 | LONG plSamples = 0; |
394 | LONG plSamples = 0; |
398 | //res = pStream1->Read(i, 1, buffer_compressed, bufsiz_compressed, &plBytes, &plSamples); |
395 | //res = pStream1->Read(i, 1, buffer_compressed, bufsiz_compressed, &plBytes, &plSamples); |
399 | res = AVIStreamRead(pStream1, i, 1, buffer_compressed, bufsiz_compressed, &plBytes, &plSamples); |
396 | res = AVIStreamRead(pStream1, i, 1, buffer_compressed, bufsiz_compressed, &plBytes, &plSamples); |
400 | if ((res != 0) || (plSamples == 0)) break; |
397 | if ((res != 0) || (plSamples == 0)) break; |
401 | 398 | ||
- | 399 | int plBytesUncompressed; |
|
- | 400 | if ((plBytes == 0) && (plSamples > 0)) { |
|
- | 401 | // In "Panic in the Park", frames at the end of some videos have 0 bytes data. |
|
- | 402 | // This should be interpreted as "repeat frame" (still image). So we fill it with palette #0 (transparent) |
|
- | 403 | plBytesUncompressed = bufsiz_uncompressed; |
|
- | 404 | ZeroMemory(buffer_uncompressed, bufsiz_uncompressed); |
|
- | 405 | } else { |
|
402 | Ipe16LZWDecoder* pdecoder = (Ipe16LZWDecoder*)malloc(sizeof(Ipe16LZWDecoder)); |
406 | Ipe16LZWDecoder* pdecoder = (Ipe16LZWDecoder*)malloc(sizeof(Ipe16LZWDecoder)); |
403 | if (pdecoder == NULL) return false; |
407 | if (pdecoder == NULL) return false; |
404 | ZeroMemory(pdecoder, sizeof(Ipe16LZWDecoder)); |
408 | ZeroMemory(pdecoder, sizeof(Ipe16LZWDecoder)); |
405 | unsigned char* work_buffer_compressed = buffer_compressed; |
409 | unsigned char* work_buffer_compressed = buffer_compressed; |
406 | int plBytesUncompressed = ipma_lzw_decode(&work_buffer_compressed, pdecoder, buffer_uncompressed, bufsiz_uncompressed); |
410 | plBytesUncompressed = ipma_lzw_decode(&work_buffer_compressed, pdecoder, buffer_uncompressed, bufsiz_uncompressed); |
407 | free(pdecoder); |
411 | free(pdecoder); |
- | 412 | } |
|
408 | if (plBytesUncompressed < 0) printf("WARNING: LZW Error %d at frame %d\n", plBytesUncompressed, i); |
413 | if (plBytesUncompressed < 0) fprintf(stderr, "WARNING: LZW Error %d at frame %d\n", plBytesUncompressed, i); |
409 | if (plBytesUncompressed != bufsiz_uncompressed) printf("WARNING: piBytesUncompressed != bufsiz_uncompressed\n"); |
414 | if (plBytesUncompressed != bufsiz_uncompressed) fprintf(stderr, "WARNING: piBytesUncompressed != bufsiz_uncompressed\n"); |
410 | if (plBytesUncompressed > 0) { |
415 | if (plBytesUncompressed > 0) { |
411 | char filnam[MAX_PATH]; |
416 | char filnam[MAX_PATH]; |
412 | if (AVIStreamIsKeyFrame(pStream1, i)) { |
417 | if (AVIStreamIsKeyFrame(pStream1, i)) { |
413 | sprintf(filnam, "%s\\frame_%05d_key.bmp", outdir, i); |
418 | sprintf(filnam, "%s\\frame_%05d_key.bmp", outdir, i); |
414 | } else { |
419 | } else { |
Line 423... | Line 428... | ||
423 | free(pstrf); |
428 | free(pstrf); |
424 | free(buffer_compressed); |
429 | free(buffer_compressed); |
425 | free(buffer_uncompressed); |
430 | free(buffer_uncompressed); |
426 | } |
431 | } |
427 | 432 | ||
428 | printf("%s: %d frames written to %s\n", filename, framesWritten, outdir); |
433 | fprintf(stdout, "%s: %d frames written to %s\n", filename, framesWritten, outdir); |
429 | 434 | ||
430 | AVIStreamRelease(pStream1); |
435 | AVIStreamRelease(pStream1); |
431 | AVIFileRelease(pFile); |
436 | AVIFileRelease(pFile); |
432 | return true; |
437 | return true; |
433 | } |
438 | } |