Changeset 6857


Ignore:
Timestamp:
08/30/10 14:10:09 (9 years ago)
Author:
melissa
Message:

Added support for multi-chunk AVI files.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/bio-formats/src/loci/formats/in/AVIReader.java

    r6754 r6857  
    6868  private Vector<Long> lengths; 
    6969 
     70  private String listString; 
    7071  private String type = "error"; 
    7172  private String fcc = "error"; 
     
    210211    super.close(fileOnly); 
    211212    if (!fileOnly) { 
     213      listString = null; 
    212214      offsets = null; 
    213215      lengths = null; 
     
    239241    lastImageNo = -1; 
    240242 
    241     String listString; 
    242  
     243    while (in.getFilePointer() < in.length() - 8) { 
     244      readChunk(); 
     245    } 
     246    LOGGER.info("Populating metadata"); 
     247 
     248    core[0].imageCount = offsets.size(); 
     249    core[0].sizeZ = 1; 
     250    core[0].sizeT = getImageCount(); 
     251    core[0].littleEndian = true; 
     252    core[0].interleaved = bmpBitsPerPixel != 16; 
     253 
     254    if (bmpBitsPerPixel == 32) { 
     255      core[0].sizeC = 4; 
     256      core[0].rgb = true; 
     257    } 
     258    else if (bytesPerPlane == 0 || bmpBitsPerPixel == 24) { 
     259      core[0].rgb = bmpBitsPerPixel > 8 || (bmpCompression != 0 && lut == null); 
     260      core[0].sizeC = isRGB() ? 3 : 1; 
     261    } 
     262    else { 
     263      core[0].sizeC = bytesPerPlane / 
     264        (getSizeX() * getSizeY() * (bmpBitsPerPixel / 8)); 
     265      core[0].rgb = getSizeC() > 1; 
     266    } 
     267    core[0].dimensionOrder = isRGB() ? "XYCTZ" : "XYTCZ"; 
     268    core[0].falseColor = false; 
     269    core[0].metadataComplete = true; 
     270    core[0].indexed = lut != null && !isRGB(); 
     271 
     272    if (bmpBitsPerPixel <= 8) { 
     273      core[0].pixelType = FormatTools.UINT8; 
     274      core[0].bitsPerPixel = bmpBitsPerPixel; 
     275    } 
     276    else if (bmpBitsPerPixel == 16) core[0].pixelType = FormatTools.UINT16; 
     277    else if (bmpBitsPerPixel == 24 || bmpBitsPerPixel == 32) { 
     278      core[0].pixelType = FormatTools.UINT8; 
     279    } 
     280    else { 
     281      throw new FormatException( 
     282          "Unknown matching for pixel bit width of: " + bmpBitsPerPixel); 
     283    } 
     284 
     285    if (bmpCompression != 0) core[0].pixelType = FormatTools.UINT8; 
     286 
     287    MetadataStore store = makeFilterMetadata(); 
     288    MetadataTools.populatePixels(store, this); 
     289    MetadataTools.setDefaultCreationDate(store, id, 0); 
     290  } 
     291 
     292  // -- Helper methods -- 
     293 
     294  private byte[] uncompress(int no, byte[] buf) 
     295    throws FormatException, IOException 
     296  { 
     297    CodecOptions options = new CodecOptions(); 
     298    options.width = getSizeX(); 
     299    options.height = getSizeY(); 
     300    options.previousImage = (lastImageNo == no - 1) ? lastImage : null; 
     301    options.bitsPerSample = bmpBitsPerPixel; 
     302 
     303    if (bmpCompression == MSRLE) { 
     304      byte[] b = new byte[(int) lengths.get(no).longValue()]; 
     305      in.read(b); 
     306      MSRLECodec codec = new MSRLECodec(); 
     307      buf = codec.decompress(b, options); 
     308      lastImage = buf; 
     309      lastImageNo = no; 
     310    } 
     311    else if (bmpCompression == MS_VIDEO) { 
     312      MSVideoCodec codec = new MSVideoCodec(); 
     313      buf = codec.decompress(in, options); 
     314      lastImage = buf; 
     315      lastImageNo = no; 
     316    } 
     317    /* 
     318    else if (bmpCompression == CINEPAK) { 
     319      Object[] options = new Object[2]; 
     320      options[0] = new Integer(bmpBitsPerPixel); 
     321      options[1] = lastImage; 
     322 
     323      CinepakCodec codec = new CinepakCodec(); 
     324      buf = codec.decompress(b, options); 
     325      lastImage = buf; 
     326      if (no == core[0].imageCount - 1) lastImage = null; 
     327      return buf; 
     328    } 
     329    */ 
     330    else { 
     331      throw new FormatException("Unsupported compression : " + bmpCompression); 
     332    } 
     333    return buf; 
     334  } 
     335 
     336  private void readChunkHeader() throws IOException { 
     337    readTypeAndSize(); 
     338    fcc = in.readString(4); 
     339  } 
     340 
     341  private void readTypeAndSize() throws IOException { 
     342    type = in.readString(4); 
     343    size = in.readInt(); 
     344  } 
     345 
     346  private void readChunk() throws FormatException, IOException { 
    243347    readChunkHeader(); 
    244348 
    245349    if (type.equals("RIFF")) { 
    246       if (!fcc.equals("AVI ")) { 
     350      if (!fcc.startsWith("AVI")) { 
    247351        throw new FormatException("Sorry, AVI RIFF format not found."); 
    248352      } 
    249353    } 
    250     else throw new FormatException("Not an AVI file"); 
     354    else if (in.getFilePointer() == 12) { 
     355      throw new FormatException("Not an AVI file"); 
     356    } 
     357    else return; 
    251358 
    252359    pos = in.getFilePointer(); 
     
    441548 
    442549              spos = in.getFilePointer(); 
    443               readTypeAndSize(); 
    444               if (type.startsWith("ix")) { 
    445                 in.skipBytes(size); 
     550              boolean end = false; 
     551              while (!end) { 
    446552                readTypeAndSize(); 
     553                String oldType = type; 
     554                if (type.startsWith("ix")) { 
     555                  in.skipBytes(size); 
     556                  readTypeAndSize(); 
     557                } 
     558 
     559                String check = type.substring(2); 
     560                boolean foundPixels = false; 
     561                while (check.equals("db") || check.equals("dc") || 
     562                  check.equals("wb")) 
     563                { 
     564                  foundPixels = true; 
     565                  if (check.startsWith("d")) { 
     566                    if (size > 0 || bmpCompression != 0) { 
     567                      offsets.add(new Long(in.getFilePointer())); 
     568                      lengths.add(new Long(size)); 
     569                      in.skipBytes(size); 
     570                    } 
     571                  } 
     572 
     573                  spos = in.getFilePointer(); 
     574                  if (spos + 8 >= in.length()) return; 
     575 
     576                  readTypeAndSize(); 
     577                  if (type.equals("JUNK")) { 
     578                    in.skipBytes(size); 
     579                    spos = in.getFilePointer(); 
     580                    readTypeAndSize(); 
     581                  } 
     582                  check = type.substring(2); 
     583                } 
     584                in.seek(spos); 
     585                if (!oldType.startsWith("ix") && !foundPixels) { 
     586                  end = true; 
     587                } 
    447588              } 
    448  
    449               String check = type.substring(2); 
    450               while (check.equals("db") || check.equals("dc") || 
    451                 check.equals("wb")) 
    452               { 
    453                 if (check.startsWith("d")) { 
    454                   if (size > 0 || bmpCompression != 0) { 
    455                     offsets.add(new Long(in.getFilePointer())); 
    456                     lengths.add(new Long(size)); 
    457                     in.skipBytes(size); 
    458                   } 
    459                 } 
    460  
    461                 spos = in.getFilePointer(); 
    462  
    463                 readTypeAndSize(); 
    464                 if (type.equals("JUNK")) { 
    465                   in.skipBytes(size); 
    466                   spos = in.getFilePointer(); 
    467                   readTypeAndSize(); 
    468                 } 
    469                 check = type.substring(2); 
    470               } 
    471               in.seek(spos); 
    472589            } 
    473590          } 
     
    481598        // skipping unknown block 
    482599        readTypeAndSize(); 
    483         if (in.getFilePointer() + 8 < in.length()) { 
     600        if (in.getFilePointer() + 8 < in.length() && !type.equals("idx1")) { 
    484601          readTypeAndSize(); 
    485602        } 
    486         else break; 
     603        else if (!type.equals("idx1")) break; 
    487604        if (in.getFilePointer() + size + 4 <= in.length()) { 
    488605          in.skipBytes(size); 
    489606        } 
     607        if (type.equals("idx1")) break; 
    490608      } 
    491609      pos = in.getFilePointer(); 
    492610    } 
    493     LOGGER.info("Populating metadata"); 
    494  
    495     core[0].imageCount = offsets.size(); 
    496     core[0].sizeZ = 1; 
    497     core[0].sizeT = getImageCount(); 
    498     core[0].littleEndian = true; 
    499     core[0].interleaved = bmpBitsPerPixel != 16; 
    500  
    501     if (bmpBitsPerPixel == 32) { 
    502       core[0].sizeC = 4; 
    503       core[0].rgb = true; 
    504     } 
    505     else if (bytesPerPlane == 0 || bmpBitsPerPixel == 24) { 
    506       core[0].rgb = bmpBitsPerPixel > 8 || (bmpCompression != 0 && lut == null); 
    507       core[0].sizeC = isRGB() ? 3 : 1; 
    508     } 
    509     else { 
    510       core[0].sizeC = bytesPerPlane / 
    511         (getSizeX() * getSizeY() * (bmpBitsPerPixel / 8)); 
    512       core[0].rgb = getSizeC() > 1; 
    513     } 
    514     core[0].dimensionOrder = isRGB() ? "XYCTZ" : "XYTCZ"; 
    515     core[0].falseColor = false; 
    516     core[0].metadataComplete = true; 
    517     core[0].indexed = lut != null && !isRGB(); 
    518  
    519     if (bmpBitsPerPixel <= 8) { 
    520       core[0].pixelType = FormatTools.UINT8; 
    521       core[0].bitsPerPixel = bmpBitsPerPixel; 
    522     } 
    523     else if (bmpBitsPerPixel == 16) core[0].pixelType = FormatTools.UINT16; 
    524     else if (bmpBitsPerPixel == 24 || bmpBitsPerPixel == 32) { 
    525       core[0].pixelType = FormatTools.UINT8; 
    526     } 
    527     else { 
    528       throw new FormatException( 
    529           "Unknown matching for pixel bit width of: " + bmpBitsPerPixel); 
    530     } 
    531  
    532     if (bmpCompression != 0) core[0].pixelType = FormatTools.UINT8; 
    533  
    534     MetadataStore store = makeFilterMetadata(); 
    535     MetadataTools.populatePixels(store, this); 
    536     MetadataTools.setDefaultCreationDate(store, id, 0); 
    537   } 
    538  
    539   // -- Helper methods -- 
    540  
    541   private byte[] uncompress(int no, byte[] buf) 
    542     throws FormatException, IOException 
    543   { 
    544     CodecOptions options = new CodecOptions(); 
    545     options.width = getSizeX(); 
    546     options.height = getSizeY(); 
    547     options.previousImage = (lastImageNo == no - 1) ? lastImage : null; 
    548     options.bitsPerSample = bmpBitsPerPixel; 
    549  
    550     if (bmpCompression == MSRLE) { 
    551       byte[] b = new byte[(int) lengths.get(no).longValue()]; 
    552       in.read(b); 
    553       MSRLECodec codec = new MSRLECodec(); 
    554       buf = codec.decompress(b, options); 
    555       lastImage = buf; 
    556       lastImageNo = no; 
    557     } 
    558     else if (bmpCompression == MS_VIDEO) { 
    559       MSVideoCodec codec = new MSVideoCodec(); 
    560       buf = codec.decompress(in, options); 
    561       lastImage = buf; 
    562       lastImageNo = no; 
    563     } 
    564     /* 
    565     else if (bmpCompression == CINEPAK) { 
    566       Object[] options = new Object[2]; 
    567       options[0] = new Integer(bmpBitsPerPixel); 
    568       options[1] = lastImage; 
    569  
    570       CinepakCodec codec = new CinepakCodec(); 
    571       buf = codec.decompress(b, options); 
    572       lastImage = buf; 
    573       if (no == core[0].imageCount - 1) lastImage = null; 
    574       return buf; 
    575     } 
    576     */ 
    577     else { 
    578       throw new FormatException("Unsupported compression : " + bmpCompression); 
    579     } 
    580     return buf; 
    581   } 
    582  
    583   private void readChunkHeader() throws IOException { 
    584     readTypeAndSize(); 
    585     fcc = in.readString(4); 
    586   } 
    587  
    588   private void readTypeAndSize() throws IOException { 
    589     type = in.readString(4); 
    590     size = in.readInt(); 
    591611  } 
    592612 
Note: See TracChangeset for help on using the changeset viewer.