if (type == 0) { //reached endPosition without finding if (throwNotFoundException) throw new Exception("Required item '"+fourccString(fourcc)+"' not found"); else return -1; nextPos = raFile.getFilePointer() + size; if (nextPos>endPosition || nextPos>fileSize) { errorText = "AVI File Error: '"+fourccString(type)+"' @ 0x"+Long.toHexString(raFile.getFilePointer()-8)+" has invalid length. File damaged/truncated?"; type = readInt(); if (verbose) IJ.log("Search for '"+fourccString(fourcc)+"', found "+fourccString(type)+"' data "+posSizeString(nextPos-size, size)); if (type==fourcc) { contentOk = readContents(fourcc, nextPos); } else if (verbose) IJ.log("'"+fourccString(type)+"', ignored"); raFile.seek(nextPos); if (contentOk)
/** Find the next position of fourcc or LIST fourcc, but does not read it, only * returns the first position inside the fourcc chunk and puts the file pointer * behind the fourcc chunk (if successful). * If not found, returns -1 */ private long findFourccAndSkip(int fourcc, boolean isList, long endPosition) throws IOException { while (true) { int type = readType(endPosition); if (type == 0) //reached endPosition without finding return -1; long size = readInt() & SIZE_MASK; long chunkPos = raFile.getFilePointer(); long nextPos = chunkPos + size; //note that 'size' of a list includes the 'type' that follows now if (isList && type == FOURCC_LIST) type = readInt(); if (verbose) IJ.log("Searching for (to skip) '"+fourccString(fourcc)+"', found "+fourccString(type)+ "' data "+posSizeString(chunkPos, size)); raFile.seek(nextPos); if (type == fourcc) return chunkPos; //found and skipped, breaks the loop } }
/** Find the next position of fourcc or LIST fourcc, but does not read it, only * returns the first position inside the fourcc chunk and puts the file pointer * behind the fourcc chunk (if successful). * If not found, returns -1 */ private long findFourccAndSkip(int fourcc, boolean isList, long endPosition) throws IOException { while (true) { int type = readType(endPosition); if (type == 0) //reached endPosition without finding return -1; long size = readInt() & SIZE_MASK; long chunkPos = raFile.getFilePointer(); long nextPos = chunkPos + size; //note that 'size' of a list includes the 'type' that follows now if (isList && type == FOURCC_LIST) type = readInt(); if (verbose) IJ.log("Searching for (to skip) '"+fourccString(fourcc)+"', found "+fourccString(type)+ "' data "+posSizeString(chunkPos, size)); raFile.seek(nextPos); if (type == fourcc) return chunkPos; //found and skipped, breaks the loop } }
if (type == 0) { //reached endPosition without finding if (throwNotFoundException) throw new Exception("Required item '"+fourccString(fourcc)+"' not found"); else return -1; nextPos = raFile.getFilePointer() + size; if (nextPos>endPosition || nextPos>fileSize) { errorText = "AVI File Error: '"+fourccString(type)+"' @ 0x"+Long.toHexString(raFile.getFilePointer()-8)+" has invalid length. File damaged/truncated?"; type = readInt(); if (verbose) IJ.log("Search for '"+fourccString(fourcc)+"', found "+fourccString(type)+"' data "+posSizeString(nextPos-size, size)); if (type==fourcc) { contentOk = readContents(fourcc, nextPos); } else if (verbose) IJ.log("'"+fourccString(type)+"', ignored"); raFile.seek(nextPos); if (contentOk)
/** Open the file with given path and read its header */ private void openAndReadHeader (String path) throws Exception, IOException { startTime = System.currentTimeMillis(); if (verbose) IJ.log("OPEN AND READ AVI FILE HEADER "+timeString()); File file = new File(path); // o p e n raFile = new RandomAccessFile(file, "r"); raFilePath = path; fileSize = raFile.length(); int fileType = readInt(); // f i l e h e a d e r if (verbose) IJ.log("File header: File type='"+fourccString(fileType)+"' (should be 'RIFF')"+timeString()); if (fileType != FOURCC_RIFF) throw new Exception("Not an AVI file."); aviSize = readInt() & SIZE_MASK; //size of AVI chunk int riffType = readInt(); if (verbose) IJ.log("File header: RIFF type='"+fourccString(riffType)+"' (should be 'AVI ')"); if (riffType != FOURCC_AVI) throw new Exception("Not an AVI file."); findFourccAndRead(FOURCC_hdrl, true, fileSize, true); startTime -= System.currentTimeMillis(); //becomes minus elapsed Time headerOK = true; }
/** Open the file with given path and read its header */ private void openAndReadHeader (String path) throws Exception, IOException { startTime = System.currentTimeMillis(); if (verbose) IJ.log("OPEN AND READ AVI FILE HEADER "+timeString()); File file = new File(path); // o p e n raFile = new RandomAccessFile(file, "r"); raFilePath = path; fileSize = raFile.length(); int fileType = readInt(); // f i l e h e a d e r if (verbose) IJ.log("File header: File type='"+fourccString(fileType)+"' (should be 'RIFF')"+timeString()); if (fileType != FOURCC_RIFF) throw new Exception("Not an AVI file."); aviSize = readInt() & SIZE_MASK; //size of AVI chunk int riffType = readInt(); if (verbose) IJ.log("File header: RIFF type='"+fourccString(riffType)+"' (should be 'AVI ')"); if (riffType != FOURCC_AVI) throw new Exception("Not an AVI file."); findFourccAndRead(FOURCC_hdrl, true, fileSize, true); startTime -= System.currentTimeMillis(); //becomes minus elapsed Time headerOK = true; }
/** Read AVIX chunks following the first RIFF AVI for large files (sequential reading frame-by-frame beyond the first chunk) **/ private void readAVIX(long endPosition) throws Exception, IOException { if (verbose) IJ.log("Trying to read AVIX"+timeString()); int riffType = readInt(); if (verbose) IJ.log("File header: RIFF type='"+fourccString(riffType)+"' (should be 'AVIX')"); if (riffType != FOURCC_AVIX) throw new Exception("Not an AVI file."); findFourccAndRead(FOURCC_movi, true, fileSize, true); //read movie data }
/** Read AVIX chunks following the first RIFF AVI for large files (sequential reading frame-by-frame beyond the first chunk) **/ private void readAVIX(long endPosition) throws Exception, IOException { if (verbose) IJ.log("Trying to read AVIX"+timeString()); int riffType = readInt(); if (verbose) IJ.log("File header: RIFF type='"+fourccString(riffType)+"' (should be 'AVIX')"); if (riffType != FOURCC_AVIX) throw new Exception("Not an AVI file."); findFourccAndRead(FOURCC_movi, true, fileSize, true); //read movie data }
IJ.log("MOVIE DATA "+posSizeString(endPosition-raFile.getFilePointer())+timeString()+ "\nSearching for stream "+streamNumber+": '"+ fourccString(type0xdb)+"' or '"+fourccString(type0xdc)+"' chunks"); if (isVirtual) { if (frameInfos==null) // we might have it already from reading the first chunk IJ.showProgress((double)frameNumber /lastFrameToRead); if (verbose) IJ.log(frameNumber+" movie data '"+fourccString(type)+"' "+posSizeString(size)+timeString()); if (frameNumber >= firstFrame) { if (isVirtual) if (frameNumber>lastFrameToRead) break; } else if (verbose) IJ.log("skipped '"+fourccString(type)+"' "+posSizeString(size)); if (nextPos > endPosition) break; raFile.seek(nextPos);
IJ.log("MOVIE DATA "+posSizeString(endPosition-raFile.getFilePointer())+timeString()+ "\nSearching for stream "+streamNumber+": '"+ fourccString(type0xdb)+"' or '"+fourccString(type0xdc)+"' chunks"); if (isVirtual) { if (frameInfos==null) // we might have it already from reading the first chunk IJ.showProgress((double)frameNumber /lastFrameToRead); if (verbose) IJ.log(frameNumber+" movie data '"+fourccString(type)+"' "+posSizeString(size)+timeString()); if (frameNumber >= firstFrame) { if (isVirtual) if (frameNumber>lastFrameToRead) break; } else if (verbose) IJ.log("skipped '"+fourccString(type)+"' "+posSizeString(size)); if (nextPos > endPosition) break; raFile.seek(nextPos);
frameInfos.add(new long[]{framePos+8, dwSize, (long)frameNumber*dwMicroSecPerFrame}); if (verbose) IJ.log("idx1 movie data '"+fourccString(dwChunkId)+"' "+posSizeString(framePos,dwSize)+timeString());
frameInfos.add(new long[]{framePos+8, dwSize, (long)frameNumber*dwMicroSecPerFrame}); if (verbose) IJ.log("idx1 movie data '"+fourccString(dwChunkId)+"' "+posSizeString(framePos,dwSize)+timeString());
IJ.log(" bIndexType=" + bIndexType + bIndexString); IJ.log(" nEntriesInUse=" + nEntriesInUse); IJ.log(" dwChunkId='" + fourccString(dwChunkId)+"'"); if (bIndexType == AVI_INDEX_OF_CHUNKS) IJ.log(" qwBaseOffset=" + "0x"+Long.toHexString(qwBaseOffset)); int dwDuration = readInt(); //number of frames in ix00; ignored: not always trustworthy if (verbose) IJ.log(" indx entry: '" +fourccString(dwChunkId)+"' incl header "+posSizeString(qwOffset,dwSize)+timeString()); long nextIndxEntryPointer = raFile.getFilePointer(); if (verbose) IJ.log("INDEX ERROR: SKIPPED ix00, wrong stream number or type, should be "+ fourccString(type0xdb)+" or "+fourccString(type0xdc)); return; frameInfos.add(new long[] {pos, dwSize, (long) frameNumber*dwMicroSecPerFrame}); if (verbose) IJ.log("movie data "+frameNumber+" '"+fourccString(dwChunkId)+"' "+posSizeString(pos,dwSize)+timeString());
IJ.log(" bIndexType=" + bIndexType + bIndexString); IJ.log(" nEntriesInUse=" + nEntriesInUse); IJ.log(" dwChunkId='" + fourccString(dwChunkId)+"'"); if (bIndexType == AVI_INDEX_OF_CHUNKS) IJ.log(" qwBaseOffset=" + "0x"+Long.toHexString(qwBaseOffset)); int dwDuration = readInt(); //number of frames in ix00; ignored: not always trustworthy if (verbose) IJ.log(" indx entry: '" +fourccString(dwChunkId)+"' incl header "+posSizeString(qwOffset,dwSize)+timeString()); long nextIndxEntryPointer = raFile.getFilePointer(); if (verbose) IJ.log("INDEX ERROR: SKIPPED ix00, wrong stream number or type, should be "+ fourccString(type0xdb)+" or "+fourccString(type0xdc)); return; frameInfos.add(new long[] {pos, dwSize, (long) frameNumber*dwMicroSecPerFrame}); if (verbose) IJ.log("movie data "+frameNumber+" '"+fourccString(dwChunkId)+"' "+posSizeString(pos,dwSize)+timeString());
IJ.log(" biPlanes=" + biPlanes); IJ.log(" biBitCount=" + biBitCount); IJ.log(" biCompression=0x" + Integer.toHexString(biCompression)+" '"+fourccString(biCompression)+"'"); IJ.log(" biSizeImage=" + biSizeImage); IJ.log(" biXPelsPerMeter=" + biXPelsPerMeter); default: throw new Exception("Unsupported compression: "+Integer.toHexString(biCompression)+ (biCompression>=0x20202020 ? " '" + fourccString(biCompression)+"'" : "")); if (allowedBitCount!=0 && (bitCountTest & allowedBitCount)==0) throw new Exception("Unsupported: "+biBitCount+" bits/pixel for compression '"+ fourccString(biCompression)+"'"); throw new Exception("Odd size ("+biWidth+"x"+biHeight+") unsupported with "+fourccString(biCompression)+" compression"); IJ.log(" > data compression=0x" + Integer.toHexString(dataCompression)+" '"+fourccString(dataCompression)+"'"); IJ.log(" > palette colors=" + biClrUsed); IJ.log(" > scan line size=" + scanLineSize);
IJ.log(" biPlanes=" + biPlanes); IJ.log(" biBitCount=" + biBitCount); IJ.log(" biCompression=0x" + Integer.toHexString(biCompression)+" '"+fourccString(biCompression)+"'"); IJ.log(" biSizeImage=" + biSizeImage); IJ.log(" biXPelsPerMeter=" + biXPelsPerMeter); default: throw new Exception("Unsupported compression: "+Integer.toHexString(biCompression)+ (biCompression>=0x20202020 ? " '" + fourccString(biCompression)+"'" : "")); if (allowedBitCount!=0 && (bitCountTest & allowedBitCount)==0) throw new Exception("Unsupported: "+biBitCount+" bits/pixel for compression '"+ fourccString(biCompression)+"'"); throw new Exception("Odd size ("+biWidth+"x"+biHeight+") unsupported with "+fourccString(biCompression)+" compression"); IJ.log(" > data compression=0x" + Integer.toHexString(dataCompression)+" '"+fourccString(dataCompression)+"'"); IJ.log(" > palette colors=" + biClrUsed); IJ.log(" > scan line size=" + scanLineSize);
if (streamType != FOURCC_vids) { if (verbose) IJ.log("Non-video Stream '"+fourccString(streamType)+" skipped"); streamNumber++; return false; return true; throw new Exception("Program error, type "+fourccString(fourcc));
if (streamType != FOURCC_vids) { if (verbose) IJ.log("Non-video Stream '"+fourccString(streamType)+" skipped"); streamNumber++; return false; return true; throw new Exception("Program error, type "+fourccString(fourcc));
IJ.log(" fccStreamHandler='" + fourccString(fccStreamHandler)+"'"); IJ.log(" dwStreamFlags=" + dwStreamFlags); IJ.log(" wPriority,wLanguage=" + dwPriorityLanguage);
IJ.log(" fccStreamHandler='" + fourccString(fccStreamHandler)+"'"); IJ.log(" dwStreamFlags=" + dwStreamFlags); IJ.log(" wPriority,wLanguage=" + dwPriorityLanguage);