Changeset 2008


Ignore:
Timestamp:
01/03/07 14:33:20 (13 years ago)
Author:
melissa
Message:

Allow file name switching.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/out/AVIWriter.java

    r2001 r2008  
    113113      file = new File(id); 
    114114      raFile = new RandomAccessFile(file, "rw"); 
    115  
    116       DataTools.writeString(raFile, "RIFF"); // signature 
    117       saveFileSize = raFile.getFilePointer(); 
    118       // Bytes 4 thru 7 contain the length of the file. This length does 
    119       // not include bytes 0 thru 7. 
    120       DataTools.writeInt(raFile, 0, true); // for now write 0 for size 
    121       DataTools.writeString(raFile, "AVI "); // RIFF type 
    122       // Write the first LIST chunk, which contains 
    123       // information on data decoding 
    124       DataTools.writeString(raFile, "LIST"); // CHUNK signature 
    125       // Write the length of the LIST CHUNK not including the first 8 bytes 
    126       // with LIST and size. Note that the end of the LIST CHUNK is followed 
    127       // by JUNK. 
    128       saveLIST1Size = raFile.getFilePointer(); 
    129       DataTools.writeInt(raFile, (bytesPerPixel == 1) ? 1240 : 216, true); 
    130       DataTools.writeString(raFile, "hdrl"); // CHUNK type 
    131       DataTools.writeString(raFile, "avih"); // Write the avih sub-CHUNK 
    132  
    133       // Write the length of the avih sub-CHUNK (38H) not including the 
    134       // the first 8 bytes for avihSignature and the length 
    135       DataTools.writeInt(raFile, 0x38, true); 
    136  
    137       // dwMicroSecPerFrame - Write the microseconds per frame 
    138       microSecPerFrame = (int) (1.0 / fps * 1.0e6); 
    139       DataTools.writeInt(raFile, microSecPerFrame, true); 
    140  
    141       // Write the maximum data rate of the file in bytes per second 
    142       DataTools.writeInt(raFile, 0, true); // dwMaxBytesPerSec 
    143  
    144       DataTools.writeInt(raFile, 0, true); // dwReserved1 - set to 0 
    145       // dwFlags - just set the bit for AVIF_HASINDEX 
    146       DataTools.writeInt(raFile, 0x10, true); 
    147  
    148       // 10H AVIF_HASINDEX: The AVI file has an idx1 chunk containing 
    149       //   an index at the end of the file. For good performance, all 
    150       //   AVI files should contain an index. 
    151       // 20H AVIF_MUSTUSEINDEX: Index CHUNK, rather than the physical 
    152       // ordering of the chunks in the file, must be used to determine the 
    153       // order of the frames. 
    154       // 100H AVIF_ISINTERLEAVED: Indicates that the AVI file is interleaved. 
    155       //   This is used to read data from a CD-ROM more efficiently. 
    156       // 800H AVIF_TRUSTCKTYPE: USE CKType to find key frames 
    157       // 10000H AVIF_WASCAPTUREFILE: The AVI file is used for capturing 
    158       //   real-time video. Applications should warn the user before 
    159       //   writing over a file with this fla set because the user 
    160       //   probably defragmented this file. 
    161       // 20000H AVIF_COPYRIGHTED: The AVI file contains copyrighted data 
    162       //   and software. When, this flag is used, software should not 
    163       //   permit the data to be duplicated. 
     115      raFile.seek(raFile.length()); 
     116      saveFileSize = 4; 
     117      saveLIST1Size = 16;  
     118      saveLIST1subSize = 23 * 4; 
     119      frameOffset = 44; 
     120      frameOffset2 = 35 * 4; 
     121      savestrfSize = 42 * 4; 
     122      savestrnPos = savestrfSize + 44 + (bytesPerPixel == 1 ? 4 * 256 : 0); 
     123      saveJUNKsignature = savestrnPos + 16; 
     124      saveLIST2Size = 4088; 
     125      savemovi = 4092; 
     126 
     127      savedbLength = new Vector(); 
     128 
     129      dataSignature = new byte[4]; 
     130      dataSignature[0] = 48; // 0 
     131      dataSignature[1] = 48; // 0 
     132      dataSignature[2] = 100; // d 
     133      dataSignature[3] = 98; // b 
    164134 
    165135      tDim = 1; 
     
    175145      } 
    176146 
    177       frameOffset = raFile.getFilePointer(); 
    178  
    179       // dwTotalFrames - total frame number 
    180       DataTools.writeInt(raFile, zDim * tDim, true); 
    181  
    182       // dwInitialFrames -Initial frame for interleaved files. 
    183       // Noninterleaved files should specify 0. 
    184       DataTools.writeInt(raFile, 0, true); 
    185  
    186       // dwStreams - number of streams in the file - here 1 video and 
    187       // zero audio. 
    188       DataTools.writeInt(raFile, 1, true); 
    189  
    190       // dwSuggestedBufferSize - Suggested buffer size for reading the file. 
    191       // Generally, this size should be large enough to contain the largest 
    192       // chunk in the file. 
    193       DataTools.writeInt(raFile, 0, true); 
    194  
    195       // dwWidth - image width in pixels 
    196       DataTools.writeInt(raFile, xDim - xPad, true); 
    197       DataTools.writeInt(raFile, yDim, true); // dwHeight - height in pixels 
    198  
    199       // dwReserved[4] - Microsoft says to set the following 4 values to 0. 
    200       DataTools.writeInt(raFile, 0, true); 
    201       DataTools.writeInt(raFile, 0, true); 
    202       DataTools.writeInt(raFile, 0, true); 
    203       DataTools.writeInt(raFile, 0, true); 
    204  
    205       // Write the Stream line header CHUNK 
    206       DataTools.writeString(raFile, "LIST"); 
    207  
    208       // Write the size of the first LIST subCHUNK not including the first 8 
    209       // bytes with LIST and size. Note that saveLIST1subSize = saveLIST1Size + 
    210       // 76, and that the length written to saveLIST1subSize is 76 less than 
    211       // the length written to saveLIST1Size. The end of the first LIST 
    212       // subCHUNK is followed by JUNK. 
    213  
    214       saveLIST1subSize = raFile.getFilePointer(); 
    215       DataTools.writeInt(raFile, (bytesPerPixel == 1) ? 1164 : 140 , true); 
    216       DataTools.writeString(raFile, "strl");   // Write the chunk type 
    217       DataTools.writeString(raFile, "strh"); // Write the strh sub-CHUNK 
    218       DataTools.writeInt(raFile, 56, true); // Write length of strh sub-CHUNK 
    219  
    220       // fccType - Write the type of data stream - here vids for video stream 
    221       DataTools.writeString(raFile, "vids"); 
    222  
    223       // Write DIB for Microsoft Device Independent Bitmap. 
    224       // Note: Unfortunately, at least 3 other four character codes are 
    225       // sometimes used for uncompressed AVI videos: 'RGB ', 'RAW ', 0x00000000 
    226       DataTools.writeString(raFile, "DIB "); 
    227  
    228       DataTools.writeInt(raFile, 0, true); // dwFlags 
    229  
    230       // 0x00000001 AVISF_DISABLED The stram data should be rendered only when 
    231       // explicitly enabled. 
    232       // 0x00010000 AVISF_VIDEO_PALCHANGES Indicates that a palette change is 
    233       // included in the AVI file. This flag warns the playback software that 
    234       // it will need to animate the palette. 
    235  
    236       // dwPriority - priority of a stream type. For example, in a file with 
    237       // multiple audio streams, the one with the highest priority might be the 
    238       // default one. 
    239       DataTools.writeInt(raFile, 0, true); 
    240  
    241       // dwInitialFrames - Specifies how far audio data is skewed ahead of 
    242       // video frames in interleaved files. Typically, this is about 0.75 
    243       // seconds. In interleaved files specify the number of frames in the file 
    244       // prior to the initial frame of the AVI sequence. 
    245       // Noninterleaved files should use zero. 
    246       DataTools.writeInt(raFile, 0, true); 
    247  
    248       // rate/scale = samples/second 
    249       DataTools.writeInt(raFile, 1, true); // dwScale 
    250  
    251       //  dwRate - frame rate for video streams 
    252       DataTools.writeInt(raFile, fps, true); 
    253  
    254       // dwStart - this field is usually set to zero 
    255       DataTools.writeInt(raFile, 0, true); 
    256  
    257       // dwLength - playing time of AVI file as defined by scale and rate 
    258       // Set equal to the number of frames 
    259       frameOffset2 = raFile.getFilePointer(); 
    260       DataTools.writeInt(raFile, tDim * zDim, true); 
    261  
    262       // dwSuggestedBufferSize - Suggested buffer size for reading the stream. 
    263       // Typically, this contains a value corresponding to the largest chunk 
    264       // in a stream. 
    265       DataTools.writeInt(raFile, 0, true); 
    266  
    267       // dwQuality - encoding quality given by an integer between 0 and 10,000. 
    268       // If set to -1, drivers use the default quality value. 
    269       DataTools.writeInt(raFile, -1, true); 
    270  
    271       // dwSampleSize # 
    272       // 0 if the video frames may or may not vary in size 
    273       // If 0, each sample of data(such as a video frame) must be in a separate 
    274       // chunk. If nonzero, then multiple samples of data can be grouped into 
    275       // a single chunk within the file. 
    276       DataTools.writeInt(raFile, 0, true); 
    277  
    278       // rcFrame - Specifies the destination rectangle for a text or video 
    279       // stream within the movie rectangle specified by the dwWidth and 
    280       // dwHeight members of the AVI main header structure. The rcFrame member 
    281       // is typically used in support of multiple video streams. Set this 
    282       // rectangle to the coordinates corresponding to the movie rectangle to 
    283       // update the whole movie rectangle. Units for this member are pixels. 
    284       // The upper-left corner of the destination rectangle is relative to the 
    285       // upper-left corner of the movie rectangle. 
    286       DataTools.writeShort(raFile, (short) 0, true); // left 
    287       DataTools.writeShort(raFile, (short) 0, true); // top 
    288       DataTools.writeShort(raFile, (short) 0, true); // right 
    289       DataTools.writeShort(raFile, (short) 0, true); // bottom 
    290  
    291       // Write the size of the stream format CHUNK not including the first 8 
    292       // bytes for strf and the size. Note that the end of the stream format 
    293       // CHUNK is followed by strn. 
    294       DataTools.writeString(raFile, "strf"); // Write the stream format chunk 
    295  
    296       savestrfSize = raFile.getFilePointer(); 
    297  
    298       // write the strf CHUNK size 
    299       DataTools.writeInt(raFile, (bytesPerPixel == 1) ? 1068 : 44, true); 
    300  
    301       // Applications should use this size to determine which BITMAPINFO header 
    302       // structure is being used. This size includes this biSize field. 
    303       // biSize- Write header size of BITMAPINFO header structure 
    304  
    305       DataTools.writeInt(raFile, 40, true); 
    306  
    307       // biWidth - image width in pixels 
    308       DataTools.writeInt(raFile, xDim - xPad, true); 
    309  
    310       // biHeight - image height in pixels. If height is positive, the bitmap 
    311       // is a bottom up DIB and its origin is in the lower left corner. If 
    312       // height is negative, the bitmap is a top-down DIB and its origin is the 
    313       // upper left corner. This negative sign feature is supported by the 
    314       // Windows Media Player, but it is not supported by PowerPoint. 
    315       DataTools.writeInt(raFile, yDim, true); 
    316  
    317       // biPlanes - number of color planes in which the data is stored 
    318       // This must be set to 1. 
    319       DataTools.writeShort(raFile, 1, true); 
    320  
    321       int bitsPerPixel = (bytesPerPixel == 3) ? 24 : 8; 
    322  
    323       // biBitCount - number of bits per pixel # 
    324       // 0L for BI_RGB, uncompressed data as bitmap 
    325       DataTools.writeShort(raFile, (short) bitsPerPixel, true); 
    326  
    327       //writeInt(bytesPerPixel * xDim * yDim * zDim * tDim); // biSizeImage # 
    328       DataTools.writeInt(raFile, 0, true); // biSizeImage # 
    329       DataTools.writeInt(raFile, 0, true); // biCompression - compression type 
    330       // biXPelsPerMeter - horizontal resolution in pixels 
    331       DataTools.writeInt(raFile, 0, true); 
    332       // biYPelsPerMeter - vertical resolution in pixels per meter 
    333       DataTools.writeInt(raFile, 0, true); 
    334       if (bitsPerPixel == 8) 
    335         DataTools.writeInt(raFile, 256, true); // biClrUsed 
    336       else 
    337         DataTools.writeInt(raFile, 0, true); // biClrUsed 
    338  
    339       // biClrImportant - specifies that the first x colors of the color table 
    340       // are important to the DIB. If the rest of the colors are not available, 
    341       // the image still retains its meaning in an acceptable manner. When this 
    342       // field is set to zero, all the colors are important, or, rather, their 
    343       // relative importance has not been computed. 
    344       DataTools.writeInt(raFile, 0, true); 
    345  
    346       // Write the LUTa.getExtents()[1] color table entries here. They are 
    347       // written: blue byte, green byte, red byte, 0 byte 
    348       if (bytesPerPixel == 1) { 
    349         byte[] lutWrite = new byte[4 * 256]; 
    350         for (int i=0; i<256; i++) { 
    351           lutWrite[4*i] = (byte) i; // blue 
    352           lutWrite[4*i+1] = (byte) i; // green 
    353           lutWrite[4*i+2] = (byte) i; // red 
    354           lutWrite[4*i+3] = 0; 
     147      if (raFile.length() == 0) { 
     148        DataTools.writeString(raFile, "RIFF"); // signature 
     149        // Bytes 4 thru 7 contain the length of the file. This length does 
     150        // not include bytes 0 thru 7. 
     151        DataTools.writeInt(raFile, 0, true); // for now write 0 for size 
     152        DataTools.writeString(raFile, "AVI "); // RIFF type 
     153        // Write the first LIST chunk, which contains 
     154        // information on data decoding 
     155        DataTools.writeString(raFile, "LIST"); // CHUNK signature 
     156        // Write the length of the LIST CHUNK not including the first 8 bytes 
     157        // with LIST and size. Note that the end of the LIST CHUNK is followed 
     158        // by JUNK. 
     159        DataTools.writeInt(raFile, (bytesPerPixel == 1) ? 1240 : 216, true); 
     160        DataTools.writeString(raFile, "hdrl"); // CHUNK type 
     161        DataTools.writeString(raFile, "avih"); // Write the avih sub-CHUNK 
     162 
     163        // Write the length of the avih sub-CHUNK (38H) not including the 
     164        // the first 8 bytes for avihSignature and the length 
     165        DataTools.writeInt(raFile, 0x38, true); 
     166 
     167        // dwMicroSecPerFrame - Write the microseconds per frame 
     168        microSecPerFrame = (int) (1.0 / fps * 1.0e6); 
     169        DataTools.writeInt(raFile, microSecPerFrame, true); 
     170 
     171        // Write the maximum data rate of the file in bytes per second 
     172        DataTools.writeInt(raFile, 0, true); // dwMaxBytesPerSec 
     173 
     174        DataTools.writeInt(raFile, 0, true); // dwReserved1 - set to 0 
     175        // dwFlags - just set the bit for AVIF_HASINDEX 
     176        DataTools.writeInt(raFile, 0x10, true); 
     177 
     178        // 10H AVIF_HASINDEX: The AVI file has an idx1 chunk containing 
     179        //   an index at the end of the file. For good performance, all 
     180        //   AVI files should contain an index. 
     181        // 20H AVIF_MUSTUSEINDEX: Index CHUNK, rather than the physical 
     182        // ordering of the chunks in the file, must be used to determine the 
     183        // order of the frames. 
     184        // 100H AVIF_ISINTERLEAVED: Indicates that the AVI file is interleaved. 
     185        //   This is used to read data from a CD-ROM more efficiently. 
     186        // 800H AVIF_TRUSTCKTYPE: USE CKType to find key frames 
     187        // 10000H AVIF_WASCAPTUREFILE: The AVI file is used for capturing 
     188        //   real-time video. Applications should warn the user before 
     189        //   writing over a file with this fla set because the user 
     190        //   probably defragmented this file. 
     191        // 20000H AVIF_COPYRIGHTED: The AVI file contains copyrighted data 
     192        //   and software. When, this flag is used, software should not 
     193        //   permit the data to be duplicated. 
     194 
     195        // dwTotalFrames - total frame number 
     196        DataTools.writeInt(raFile, zDim * tDim, true); 
     197 
     198        // dwInitialFrames -Initial frame for interleaved files. 
     199        // Noninterleaved files should specify 0. 
     200        DataTools.writeInt(raFile, 0, true); 
     201 
     202        // dwStreams - number of streams in the file - here 1 video and 
     203        // zero audio. 
     204        DataTools.writeInt(raFile, 1, true); 
     205 
     206        // dwSuggestedBufferSize - Suggested buffer size for reading the file. 
     207        // Generally, this size should be large enough to contain the largest 
     208        // chunk in the file. 
     209        DataTools.writeInt(raFile, 0, true); 
     210 
     211        // dwWidth - image width in pixels 
     212        DataTools.writeInt(raFile, xDim - xPad, true); 
     213        DataTools.writeInt(raFile, yDim, true); // dwHeight - height in pixels 
     214 
     215        // dwReserved[4] - Microsoft says to set the following 4 values to 0. 
     216        DataTools.writeInt(raFile, 0, true); 
     217        DataTools.writeInt(raFile, 0, true); 
     218        DataTools.writeInt(raFile, 0, true); 
     219        DataTools.writeInt(raFile, 0, true); 
     220 
     221        // Write the Stream line header CHUNK 
     222        DataTools.writeString(raFile, "LIST"); 
     223 
     224        // Write the size of the first LIST subCHUNK not including the first 8 
     225        // bytes with LIST and size. Note that saveLIST1subSize = saveLIST1Size + 
     226        // 76, and that the length written to saveLIST1subSize is 76 less than 
     227        // the length written to saveLIST1Size. The end of the first LIST 
     228        // subCHUNK is followed by JUNK. 
     229 
     230        DataTools.writeInt(raFile, (bytesPerPixel == 1) ? 1164 : 140 , true); 
     231        DataTools.writeString(raFile, "strl");   // Write the chunk type 
     232        DataTools.writeString(raFile, "strh"); // Write the strh sub-CHUNK 
     233        DataTools.writeInt(raFile, 56, true); // Write length of strh sub-CHUNK 
     234 
     235        // fccType - Write the type of data stream - here vids for video stream 
     236        DataTools.writeString(raFile, "vids"); 
     237 
     238        // Write DIB for Microsoft Device Independent Bitmap. 
     239        // Note: Unfortunately, at least 3 other four character codes are 
     240        // sometimes used for uncompressed AVI videos: 'RGB ', 'RAW ', 0x00000000 
     241        DataTools.writeString(raFile, "DIB "); 
     242 
     243        DataTools.writeInt(raFile, 0, true); // dwFlags 
     244 
     245        // 0x00000001 AVISF_DISABLED The stram data should be rendered only when 
     246        // explicitly enabled. 
     247        // 0x00010000 AVISF_VIDEO_PALCHANGES Indicates that a palette change is 
     248        // included in the AVI file. This flag warns the playback software that 
     249        // it will need to animate the palette. 
     250 
     251        // dwPriority - priority of a stream type. For example, in a file with 
     252        // multiple audio streams, the one with the highest priority might be the 
     253        // default one. 
     254        DataTools.writeInt(raFile, 0, true); 
     255 
     256        // dwInitialFrames - Specifies how far audio data is skewed ahead of 
     257        // video frames in interleaved files. Typically, this is about 0.75 
     258        // seconds. In interleaved files specify the number of frames in the file 
     259        // prior to the initial frame of the AVI sequence. 
     260        // Noninterleaved files should use zero. 
     261        DataTools.writeInt(raFile, 0, true); 
     262 
     263        // rate/scale = samples/second 
     264        DataTools.writeInt(raFile, 1, true); // dwScale 
     265 
     266        //  dwRate - frame rate for video streams 
     267        DataTools.writeInt(raFile, fps, true); 
     268   
     269        // dwStart - this field is usually set to zero 
     270        DataTools.writeInt(raFile, 0, true); 
     271 
     272        // dwLength - playing time of AVI file as defined by scale and rate 
     273        // Set equal to the number of frames 
     274        DataTools.writeInt(raFile, tDim * zDim, true); 
     275 
     276        // dwSuggestedBufferSize - Suggested buffer size for reading the stream. 
     277        // Typically, this contains a value corresponding to the largest chunk 
     278        // in a stream. 
     279        DataTools.writeInt(raFile, 0, true); 
     280 
     281        // dwQuality - encoding quality given by an integer between 0 and 10,000. 
     282        // If set to -1, drivers use the default quality value. 
     283        DataTools.writeInt(raFile, -1, true); 
     284 
     285        // dwSampleSize # 
     286        // 0 if the video frames may or may not vary in size 
     287        // If 0, each sample of data(such as a video frame) must be in a separate 
     288        // chunk. If nonzero, then multiple samples of data can be grouped into 
     289        // a single chunk within the file. 
     290        DataTools.writeInt(raFile, 0, true); 
     291 
     292        // rcFrame - Specifies the destination rectangle for a text or video 
     293        // stream within the movie rectangle specified by the dwWidth and 
     294        // dwHeight members of the AVI main header structure. The rcFrame member 
     295        // is typically used in support of multiple video streams. Set this 
     296        // rectangle to the coordinates corresponding to the movie rectangle to 
     297        // update the whole movie rectangle. Units for this member are pixels. 
     298        // The upper-left corner of the destination rectangle is relative to the 
     299        // upper-left corner of the movie rectangle. 
     300        DataTools.writeShort(raFile, (short) 0, true); // left 
     301        DataTools.writeShort(raFile, (short) 0, true); // top 
     302        DataTools.writeShort(raFile, (short) 0, true); // right 
     303        DataTools.writeShort(raFile, (short) 0, true); // bottom 
     304 
     305        // Write the size of the stream format CHUNK not including the first 8 
     306        // bytes for strf and the size. Note that the end of the stream format 
     307        // CHUNK is followed by strn. 
     308        DataTools.writeString(raFile, "strf"); // Write the stream format chunk 
     309 
     310        // write the strf CHUNK size 
     311        DataTools.writeInt(raFile, (bytesPerPixel == 1) ? 1068 : 44, true); 
     312 
     313        // Applications should use this size to determine which BITMAPINFO header 
     314        // structure is being used. This size includes this biSize field. 
     315        // biSize- Write header size of BITMAPINFO header structure 
     316 
     317        DataTools.writeInt(raFile, 40, true); 
     318 
     319        // biWidth - image width in pixels 
     320        DataTools.writeInt(raFile, xDim - xPad, true); 
     321 
     322        // biHeight - image height in pixels. If height is positive, the bitmap 
     323        // is a bottom up DIB and its origin is in the lower left corner. If 
     324        // height is negative, the bitmap is a top-down DIB and its origin is the 
     325        // upper left corner. This negative sign feature is supported by the 
     326        // Windows Media Player, but it is not supported by PowerPoint. 
     327        DataTools.writeInt(raFile, yDim, true); 
     328 
     329        // biPlanes - number of color planes in which the data is stored 
     330        // This must be set to 1. 
     331        DataTools.writeShort(raFile, 1, true); 
     332 
     333        int bitsPerPixel = (bytesPerPixel == 3) ? 24 : 8; 
     334 
     335        // biBitCount - number of bits per pixel # 
     336        // 0L for BI_RGB, uncompressed data as bitmap 
     337        DataTools.writeShort(raFile, (short) bitsPerPixel, true); 
     338 
     339        //writeInt(bytesPerPixel * xDim * yDim * zDim * tDim); // biSizeImage # 
     340        DataTools.writeInt(raFile, 0, true); // biSizeImage # 
     341        DataTools.writeInt(raFile, 0, true); // biCompression - compression type 
     342        // biXPelsPerMeter - horizontal resolution in pixels 
     343        DataTools.writeInt(raFile, 0, true); 
     344        // biYPelsPerMeter - vertical resolution in pixels per meter 
     345        DataTools.writeInt(raFile, 0, true); 
     346        if (bitsPerPixel == 8) DataTools.writeInt(raFile, 256, true); 
     347        else DataTools.writeInt(raFile, 0, true); // biClrUsed 
     348 
     349        // biClrImportant - specifies that the first x colors of the color table 
     350        // are important to the DIB. If the rest of the colors are not available, 
     351        // the image still retains its meaning in an acceptable manner. When this 
     352        // field is set to zero, all the colors are important, or, rather, their 
     353        // relative importance has not been computed. 
     354        DataTools.writeInt(raFile, 0, true); 
     355 
     356        // Write the LUTa.getExtents()[1] color table entries here. They are 
     357        // written: blue byte, green byte, red byte, 0 byte 
     358        if (bytesPerPixel == 1) { 
     359          byte[] lutWrite = new byte[4 * 256]; 
     360          for (int i=0; i<256; i++) { 
     361            lutWrite[4*i] = (byte) i; // blue 
     362            lutWrite[4*i+1] = (byte) i; // green 
     363            lutWrite[4*i+2] = (byte) i; // red 
     364            lutWrite[4*i+3] = 0; 
     365          } 
     366          raFile.write(lutWrite); 
    355367        } 
    356         raFile.write(lutWrite); 
     368 
     369        raFile.seek(savestrfSize); 
     370        DataTools.writeInt(raFile, 
     371          (int) (savestrnPos - (savestrfSize + 4)), true); 
     372        raFile.seek(savestrnPos); 
     373 
     374        // Use strn to provide zero terminated text string describing the stream 
     375        DataTools.writeString(raFile, "strn"); 
     376        DataTools.writeInt(raFile, 16, true); // Write length of strn sub-CHUNK 
     377        text = new byte[16]; 
     378        text[0] = 70; // F 
     379        text[1] = 105; // i 
     380        text[2] = 108; // l 
     381        text[3] = 101; // e 
     382        text[4] = 65; // A 
     383        text[5] = 118; // v 
     384        text[6] = 105; // i 
     385        text[7] = 32; // space 
     386        text[8] = 119; // w 
     387        text[9] = 114; // r 
     388        text[10] = 105; // i 
     389        text[11] = 116; // t 
     390        text[12] = 101; // e 
     391        text[13] = 32; // space 
     392        text[14] = 32; // space 
     393        text[15] = 0; // termination byte 
     394        raFile.write(text); 
     395 
     396        raFile.seek(saveLIST1Size); 
     397        DataTools.writeInt(raFile, 
     398          (int) (saveJUNKsignature - (saveLIST1Size + 4)), true); 
     399        raFile.seek(saveLIST1subSize); 
     400        DataTools.writeInt(raFile, 
     401          (int) (saveJUNKsignature - (saveLIST1subSize + 4)), true); 
     402        raFile.seek(saveJUNKsignature); 
     403 
     404        // write a JUNK CHUNK for padding 
     405        DataTools.writeString(raFile, "JUNK"); 
     406        paddingBytes = (int) (4084 - (saveJUNKsignature + 8)); 
     407        DataTools.writeInt(raFile, paddingBytes, true); 
     408        for (int i=0; i<paddingBytes/2; i++) { 
     409          DataTools.writeShort(raFile, (short) 0, true); 
     410        } 
     411 
     412        // Write the second LIST chunk, which contains the actual data 
     413        DataTools.writeString(raFile, "LIST"); 
     414 
     415        // Write the length of the LIST CHUNK not including the first 8 bytes 
     416        // with LIST and size. The end of the second LIST CHUNK is followed by 
     417        // idx1. 
     418        saveLIST2Size = raFile.getFilePointer(); 
     419 
     420        DataTools.writeInt(raFile, 0, true);  // For now write 0 
     421        DataTools.writeString(raFile, "movi"); // Write CHUNK type 'movi' 
    357422      } 
    358  
    359       savestrnPos = raFile.getFilePointer(); 
    360       raFile.seek(savestrfSize); 
    361       DataTools.writeInt(raFile, 
    362         (int) (savestrnPos - (savestrfSize + 4)), true); 
    363       raFile.seek(savestrnPos); 
    364  
    365       // Use strn to provide zero terminated text string describing the stream 
    366       DataTools.writeString(raFile, "strn"); 
    367       DataTools.writeInt(raFile, 16, true); // Write length of strn sub-CHUNK 
    368       text = new byte[16]; 
    369       text[0] = 70; // F 
    370       text[1] = 105; // i 
    371       text[2] = 108; // l 
    372       text[3] = 101; // e 
    373       text[4] = 65; // A 
    374       text[5] = 118; // v 
    375       text[6] = 105; // i 
    376       text[7] = 32; // space 
    377       text[8] = 119; // w 
    378       text[9] = 114; // r 
    379       text[10] = 105; // i 
    380       text[11] = 116; // t 
    381       text[12] = 101; // e 
    382       text[13] = 32; // space 
    383       text[14] = 32; // space 
    384       text[15] = 0; // termination byte 
    385       raFile.write(text); 
    386  
    387       saveJUNKsignature = raFile.getFilePointer(); 
    388       raFile.seek(saveLIST1Size); 
    389       DataTools.writeInt(raFile, 
    390         (int) (saveJUNKsignature - (saveLIST1Size + 4)), true); 
    391       raFile.seek(saveLIST1subSize); 
    392       DataTools.writeInt(raFile, 
    393         (int) (saveJUNKsignature - (saveLIST1subSize + 4)), true); 
    394       raFile.seek(saveJUNKsignature); 
    395  
    396       // write a JUNK CHUNK for padding 
    397       DataTools.writeString(raFile, "JUNK"); 
    398       paddingBytes = (int) (4084 - (saveJUNKsignature + 8)); 
    399       DataTools.writeInt(raFile, paddingBytes, true); 
    400       for (int i=0; i<paddingBytes/2; i++) { 
    401         DataTools.writeShort(raFile, (short) 0, true); 
    402       } 
    403  
    404       // Write the second LIST chunk, which contains the actual data 
    405       DataTools.writeString(raFile, "LIST"); 
    406  
    407       // Write the length of the LIST CHUNK not including the first 8 bytes 
    408       // with LIST and size. The end of the second LIST CHUNK is followed by 
    409       // idx1. 
    410       saveLIST2Size = raFile.getFilePointer(); 
    411  
    412       DataTools.writeInt(raFile, 0, true);  // For now write 0 
    413       savemovi = raFile.getFilePointer(); 
    414       DataTools.writeString(raFile, "movi"); // Write CHUNK type 'movi' 
    415       savedbLength = new Vector(); 
    416  
    417       dataSignature = new byte[4]; 
    418       dataSignature[0] = 48; // 0 
    419       dataSignature[1] = 48; // 0 
    420       dataSignature[2] = 100; // d 
    421       dataSignature[3] = 98; // b 
    422423    } 
    423424 
Note: See TracChangeset for help on using the changeset viewer.