< prev index next >

src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java

Print this page




 250             return 2;
 251         }
 252         x = x - 1;
 253         x = x | (x >> 1);
 254         x = x | (x >> 2);
 255         x = x | (x >> 4);
 256         x = x | (x >> 8);
 257         x = x | (x >> 16);
 258         return x + 1;
 259     }
 260 
 261 
 262 
 263     public GIFImageWriter(GIFImageWriterSpi originatingProvider) {
 264         super(originatingProvider);
 265         if (DEBUG) {
 266             System.err.println("GIF Writer is created");
 267         }
 268     }
 269 

 270     public boolean canWriteSequence() {
 271         return true;
 272     }
 273 
 274     /**
 275      * Merges {@code inData} into {@code outData}. The supplied
 276      * metadata format name is attempted first and failing that the standard
 277      * metadata format name is attempted.
 278      */
 279     private void convertMetadata(String metadataFormatName,
 280                                  IIOMetadata inData,
 281                                  IIOMetadata outData) {
 282         String formatName = null;
 283 
 284         String nativeFormatName = inData.getNativeMetadataFormatName();
 285         if (nativeFormatName != null &&
 286             nativeFormatName.equals(metadataFormatName)) {
 287             formatName = metadataFormatName;
 288         } else {
 289             String[] extraFormatNames = inData.getExtraMetadataFormatNames();


 300 
 301         if (formatName == null &&
 302             inData.isStandardMetadataFormatSupported()) {
 303             formatName = STANDARD_METADATA_NAME;
 304         }
 305 
 306         if (formatName != null) {
 307             try {
 308                 Node root = inData.getAsTree(formatName);
 309                 outData.mergeTree(formatName, root);
 310             } catch(IIOInvalidTreeException e) {
 311                 // ignore
 312             }
 313         }
 314     }
 315 
 316     /**
 317      * Creates a default stream metadata object and merges in the
 318      * supplied metadata.
 319      */

 320     public IIOMetadata convertStreamMetadata(IIOMetadata inData,
 321                                              ImageWriteParam param) {
 322         if (inData == null) {
 323             throw new IllegalArgumentException("inData == null!");
 324         }
 325 
 326         IIOMetadata sm = getDefaultStreamMetadata(param);
 327 
 328         convertMetadata(STREAM_METADATA_NAME, inData, sm);
 329 
 330         return sm;
 331     }
 332 
 333     /**
 334      * Creates a default image metadata object and merges in the
 335      * supplied metadata.
 336      */

 337     public IIOMetadata convertImageMetadata(IIOMetadata inData,
 338                                             ImageTypeSpecifier imageType,
 339                                             ImageWriteParam param) {
 340         if (inData == null) {
 341             throw new IllegalArgumentException("inData == null!");
 342         }
 343         if (imageType == null) {
 344             throw new IllegalArgumentException("imageType == null!");
 345         }
 346 
 347         GIFWritableImageMetadata im =
 348             (GIFWritableImageMetadata)getDefaultImageMetadata(imageType,
 349                                                               param);
 350 
 351         // Save interlace flag state.
 352 
 353         boolean isProgressive = im.interlaceFlag;
 354 
 355         convertMetadata(IMAGE_METADATA_NAME, inData, im);
 356 
 357         // Undo change to interlace flag if not MODE_COPY_FROM_METADATA.
 358 
 359         if (param != null && param.canWriteProgressive() &&
 360             param.getProgressiveMode() != ImageWriteParam.MODE_COPY_FROM_METADATA) {
 361             im.interlaceFlag = isProgressive;
 362         }
 363 
 364         return im;
 365     }
 366 

 367     public void endWriteSequence() throws IOException {
 368         if (stream == null) {
 369             throw new IllegalStateException("output == null!");
 370         }
 371         if (!isWritingSequence) {
 372             throw new IllegalStateException("prepareWriteSequence() was not invoked!");
 373         }
 374         writeTrailer();
 375         resetLocal();
 376     }
 377 

 378     public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,
 379                                                ImageWriteParam param) {
 380         GIFWritableImageMetadata imageMetadata =
 381             new GIFWritableImageMetadata();
 382 
 383         // Image dimensions
 384 
 385         SampleModel sampleModel = imageType.getSampleModel();
 386 
 387         Rectangle sourceBounds = new Rectangle(sampleModel.getWidth(),
 388                                                sampleModel.getHeight());
 389         Dimension destSize = new Dimension();
 390         computeRegions(sourceBounds, destSize, param);
 391 
 392         imageMetadata.imageWidth = destSize.width;
 393         imageMetadata.imageHeight = destSize.height;
 394 
 395         // Interlacing
 396 
 397         if (param != null && param.canWriteProgressive() &&


 405 
 406         ColorModel colorModel = imageType.getColorModel();
 407 
 408         imageMetadata.localColorTable =
 409             createColorTable(colorModel, sampleModel);
 410 
 411         // Transparency
 412 
 413         if (colorModel instanceof IndexColorModel) {
 414             int transparentIndex =
 415                 ((IndexColorModel)colorModel).getTransparentPixel();
 416             if (transparentIndex != -1) {
 417                 imageMetadata.transparentColorFlag = true;
 418                 imageMetadata.transparentColorIndex = transparentIndex;
 419             }
 420         }
 421 
 422         return imageMetadata;
 423     }
 424 

 425     public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {
 426         GIFWritableStreamMetadata streamMetadata =
 427             new GIFWritableStreamMetadata();
 428         streamMetadata.version = "89a";
 429         return streamMetadata;
 430     }
 431 

 432     public ImageWriteParam getDefaultWriteParam() {
 433         return new GIFImageWriteParam(getLocale());
 434     }
 435 

 436     public void prepareWriteSequence(IIOMetadata streamMetadata)
 437       throws IOException {
 438 
 439         if (stream == null) {
 440             throw new IllegalStateException("Output is not set.");
 441         }
 442 
 443         resetLocal();
 444 
 445         // Save the possibly converted stream metadata as an instance variable.
 446         if (streamMetadata == null) {
 447             this.theStreamMetadata =
 448                 (GIFWritableStreamMetadata)getDefaultStreamMetadata(null);
 449         } else {
 450             this.theStreamMetadata = new GIFWritableStreamMetadata();
 451             convertMetadata(STREAM_METADATA_NAME, streamMetadata,
 452                             theStreamMetadata);
 453         }
 454 
 455         this.isWritingSequence = true;
 456     }
 457 

 458     public void reset() {
 459         super.reset();
 460         resetLocal();
 461     }
 462 
 463     /**
 464      * Resets locally defined instance variables.
 465      */
 466     private void resetLocal() {
 467         this.isWritingSequence = false;
 468         this.wroteSequenceHeader = false;
 469         this.theStreamMetadata = null;
 470         this.imageIndex = 0;
 471     }
 472 

 473     public void setOutput(Object output) {
 474         super.setOutput(output);
 475         if (output != null) {
 476             if (!(output instanceof ImageOutputStream)) {
 477                 throw new
 478                     IllegalArgumentException("output is not an ImageOutputStream");
 479             }
 480             this.stream = (ImageOutputStream)output;
 481             this.stream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
 482         } else {
 483             this.stream = null;
 484         }
 485     }
 486 

 487     public void write(IIOMetadata sm,
 488                       IIOImage iioimage,
 489                       ImageWriteParam p) throws IOException {
 490         if (stream == null) {
 491             throw new IllegalStateException("output == null!");
 492         }
 493         if (iioimage == null) {
 494             throw new IllegalArgumentException("iioimage == null!");
 495         }
 496         if (iioimage.hasRaster()) {
 497             throw new UnsupportedOperationException("canWriteRasters() == false!");
 498         }
 499 
 500         resetLocal();
 501 
 502         GIFWritableStreamMetadata streamMetadata;
 503         if (sm == null) {
 504             streamMetadata =
 505                 (GIFWritableStreamMetadata)getDefaultStreamMetadata(p);
 506         } else {
 507             streamMetadata =
 508                 (GIFWritableStreamMetadata)convertStreamMetadata(sm, p);
 509         }
 510 
 511         write(true, true, streamMetadata, iioimage, p);
 512     }
 513 

 514     public void writeToSequence(IIOImage image, ImageWriteParam param)
 515       throws IOException {
 516         if (stream == null) {
 517             throw new IllegalStateException("output == null!");
 518         }
 519         if (image == null) {
 520             throw new IllegalArgumentException("image == null!");
 521         }
 522         if (image.hasRaster()) {
 523             throw new UnsupportedOperationException("canWriteRasters() == false!");
 524         }
 525         if (!isWritingSequence) {
 526             throw new IllegalStateException("prepareWriteSequence() was not invoked!");
 527         }
 528 
 529         write(!wroteSequenceHeader, false, theStreamMetadata,
 530               image, param);
 531 
 532         if (!wroteSequenceHeader) {
 533             wroteSequenceHeader = true;


1302                              imageMetadata.interlaceFlag,
1303                              imageMetadata.sortFlag,
1304                              bitsPerPixel,
1305                              imageMetadata.localColorTable);
1306     }
1307 
1308     private void writeTrailer() throws IOException {
1309         stream.write(0x3b);
1310     }
1311 }
1312 
1313 class GIFImageWriteParam extends ImageWriteParam {
1314     GIFImageWriteParam(Locale locale) {
1315         super(locale);
1316         this.canWriteCompressed = true;
1317         this.canWriteProgressive = true;
1318         this.compressionTypes = new String[] {"LZW"};
1319         this.compressionType = compressionTypes[0];
1320     }
1321 

1322     public void setCompressionMode(int mode) {
1323         if (mode == MODE_DISABLED) {
1324             throw new UnsupportedOperationException("MODE_DISABLED is not supported.");
1325         }
1326         super.setCompressionMode(mode);
1327     }
1328 }


 250             return 2;
 251         }
 252         x = x - 1;
 253         x = x | (x >> 1);
 254         x = x | (x >> 2);
 255         x = x | (x >> 4);
 256         x = x | (x >> 8);
 257         x = x | (x >> 16);
 258         return x + 1;
 259     }
 260 
 261 
 262 
 263     public GIFImageWriter(GIFImageWriterSpi originatingProvider) {
 264         super(originatingProvider);
 265         if (DEBUG) {
 266             System.err.println("GIF Writer is created");
 267         }
 268     }
 269 
 270     @Override
 271     public boolean canWriteSequence() {
 272         return true;
 273     }
 274 
 275     /**
 276      * Merges {@code inData} into {@code outData}. The supplied
 277      * metadata format name is attempted first and failing that the standard
 278      * metadata format name is attempted.
 279      */
 280     private void convertMetadata(String metadataFormatName,
 281                                  IIOMetadata inData,
 282                                  IIOMetadata outData) {
 283         String formatName = null;
 284 
 285         String nativeFormatName = inData.getNativeMetadataFormatName();
 286         if (nativeFormatName != null &&
 287             nativeFormatName.equals(metadataFormatName)) {
 288             formatName = metadataFormatName;
 289         } else {
 290             String[] extraFormatNames = inData.getExtraMetadataFormatNames();


 301 
 302         if (formatName == null &&
 303             inData.isStandardMetadataFormatSupported()) {
 304             formatName = STANDARD_METADATA_NAME;
 305         }
 306 
 307         if (formatName != null) {
 308             try {
 309                 Node root = inData.getAsTree(formatName);
 310                 outData.mergeTree(formatName, root);
 311             } catch(IIOInvalidTreeException e) {
 312                 // ignore
 313             }
 314         }
 315     }
 316 
 317     /**
 318      * Creates a default stream metadata object and merges in the
 319      * supplied metadata.
 320      */
 321     @Override
 322     public IIOMetadata convertStreamMetadata(IIOMetadata inData,
 323                                              ImageWriteParam param) {
 324         if (inData == null) {
 325             throw new IllegalArgumentException("inData == null!");
 326         }
 327 
 328         IIOMetadata sm = getDefaultStreamMetadata(param);
 329 
 330         convertMetadata(STREAM_METADATA_NAME, inData, sm);
 331 
 332         return sm;
 333     }
 334 
 335     /**
 336      * Creates a default image metadata object and merges in the
 337      * supplied metadata.
 338      */
 339     @Override
 340     public IIOMetadata convertImageMetadata(IIOMetadata inData,
 341                                             ImageTypeSpecifier imageType,
 342                                             ImageWriteParam param) {
 343         if (inData == null) {
 344             throw new IllegalArgumentException("inData == null!");
 345         }
 346         if (imageType == null) {
 347             throw new IllegalArgumentException("imageType == null!");
 348         }
 349 
 350         GIFWritableImageMetadata im =
 351             (GIFWritableImageMetadata)getDefaultImageMetadata(imageType,
 352                                                               param);
 353 
 354         // Save interlace flag state.
 355 
 356         boolean isProgressive = im.interlaceFlag;
 357 
 358         convertMetadata(IMAGE_METADATA_NAME, inData, im);
 359 
 360         // Undo change to interlace flag if not MODE_COPY_FROM_METADATA.
 361 
 362         if (param != null && param.canWriteProgressive() &&
 363             param.getProgressiveMode() != ImageWriteParam.MODE_COPY_FROM_METADATA) {
 364             im.interlaceFlag = isProgressive;
 365         }
 366 
 367         return im;
 368     }
 369 
 370     @Override
 371     public void endWriteSequence() throws IOException {
 372         if (stream == null) {
 373             throw new IllegalStateException("output == null!");
 374         }
 375         if (!isWritingSequence) {
 376             throw new IllegalStateException("prepareWriteSequence() was not invoked!");
 377         }
 378         writeTrailer();
 379         resetLocal();
 380     }
 381 
 382     @Override
 383     public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,
 384                                                ImageWriteParam param) {
 385         GIFWritableImageMetadata imageMetadata =
 386             new GIFWritableImageMetadata();
 387 
 388         // Image dimensions
 389 
 390         SampleModel sampleModel = imageType.getSampleModel();
 391 
 392         Rectangle sourceBounds = new Rectangle(sampleModel.getWidth(),
 393                                                sampleModel.getHeight());
 394         Dimension destSize = new Dimension();
 395         computeRegions(sourceBounds, destSize, param);
 396 
 397         imageMetadata.imageWidth = destSize.width;
 398         imageMetadata.imageHeight = destSize.height;
 399 
 400         // Interlacing
 401 
 402         if (param != null && param.canWriteProgressive() &&


 410 
 411         ColorModel colorModel = imageType.getColorModel();
 412 
 413         imageMetadata.localColorTable =
 414             createColorTable(colorModel, sampleModel);
 415 
 416         // Transparency
 417 
 418         if (colorModel instanceof IndexColorModel) {
 419             int transparentIndex =
 420                 ((IndexColorModel)colorModel).getTransparentPixel();
 421             if (transparentIndex != -1) {
 422                 imageMetadata.transparentColorFlag = true;
 423                 imageMetadata.transparentColorIndex = transparentIndex;
 424             }
 425         }
 426 
 427         return imageMetadata;
 428     }
 429 
 430     @Override
 431     public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {
 432         GIFWritableStreamMetadata streamMetadata =
 433             new GIFWritableStreamMetadata();
 434         streamMetadata.version = "89a";
 435         return streamMetadata;
 436     }
 437 
 438     @Override
 439     public ImageWriteParam getDefaultWriteParam() {
 440         return new GIFImageWriteParam(getLocale());
 441     }
 442 
 443     @Override
 444     public void prepareWriteSequence(IIOMetadata streamMetadata)
 445       throws IOException {
 446 
 447         if (stream == null) {
 448             throw new IllegalStateException("Output is not set.");
 449         }
 450 
 451         resetLocal();
 452 
 453         // Save the possibly converted stream metadata as an instance variable.
 454         if (streamMetadata == null) {
 455             this.theStreamMetadata =
 456                 (GIFWritableStreamMetadata)getDefaultStreamMetadata(null);
 457         } else {
 458             this.theStreamMetadata = new GIFWritableStreamMetadata();
 459             convertMetadata(STREAM_METADATA_NAME, streamMetadata,
 460                             theStreamMetadata);
 461         }
 462 
 463         this.isWritingSequence = true;
 464     }
 465 
 466     @Override
 467     public void reset() {
 468         super.reset();
 469         resetLocal();
 470     }
 471 
 472     /**
 473      * Resets locally defined instance variables.
 474      */
 475     private void resetLocal() {
 476         this.isWritingSequence = false;
 477         this.wroteSequenceHeader = false;
 478         this.theStreamMetadata = null;
 479         this.imageIndex = 0;
 480     }
 481 
 482     @Override
 483     public void setOutput(Object output) {
 484         super.setOutput(output);
 485         if (output != null) {
 486             if (!(output instanceof ImageOutputStream)) {
 487                 throw new
 488                     IllegalArgumentException("output is not an ImageOutputStream");
 489             }
 490             this.stream = (ImageOutputStream)output;
 491             this.stream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
 492         } else {
 493             this.stream = null;
 494         }
 495     }
 496 
 497     @Override
 498     public void write(IIOMetadata sm,
 499                       IIOImage iioimage,
 500                       ImageWriteParam p) throws IOException {
 501         if (stream == null) {
 502             throw new IllegalStateException("output == null!");
 503         }
 504         if (iioimage == null) {
 505             throw new IllegalArgumentException("iioimage == null!");
 506         }
 507         if (iioimage.hasRaster()) {
 508             throw new UnsupportedOperationException("canWriteRasters() == false!");
 509         }
 510 
 511         resetLocal();
 512 
 513         GIFWritableStreamMetadata streamMetadata;
 514         if (sm == null) {
 515             streamMetadata =
 516                 (GIFWritableStreamMetadata)getDefaultStreamMetadata(p);
 517         } else {
 518             streamMetadata =
 519                 (GIFWritableStreamMetadata)convertStreamMetadata(sm, p);
 520         }
 521 
 522         write(true, true, streamMetadata, iioimage, p);
 523     }
 524 
 525     @Override
 526     public void writeToSequence(IIOImage image, ImageWriteParam param)
 527       throws IOException {
 528         if (stream == null) {
 529             throw new IllegalStateException("output == null!");
 530         }
 531         if (image == null) {
 532             throw new IllegalArgumentException("image == null!");
 533         }
 534         if (image.hasRaster()) {
 535             throw new UnsupportedOperationException("canWriteRasters() == false!");
 536         }
 537         if (!isWritingSequence) {
 538             throw new IllegalStateException("prepareWriteSequence() was not invoked!");
 539         }
 540 
 541         write(!wroteSequenceHeader, false, theStreamMetadata,
 542               image, param);
 543 
 544         if (!wroteSequenceHeader) {
 545             wroteSequenceHeader = true;


1314                              imageMetadata.interlaceFlag,
1315                              imageMetadata.sortFlag,
1316                              bitsPerPixel,
1317                              imageMetadata.localColorTable);
1318     }
1319 
1320     private void writeTrailer() throws IOException {
1321         stream.write(0x3b);
1322     }
1323 }
1324 
1325 class GIFImageWriteParam extends ImageWriteParam {
1326     GIFImageWriteParam(Locale locale) {
1327         super(locale);
1328         this.canWriteCompressed = true;
1329         this.canWriteProgressive = true;
1330         this.compressionTypes = new String[] {"LZW"};
1331         this.compressionType = compressionTypes[0];
1332     }
1333 
1334     @Override
1335     public void setCompressionMode(int mode) {
1336         if (mode == MODE_DISABLED) {
1337             throw new UnsupportedOperationException("MODE_DISABLED is not supported.");
1338         }
1339         super.setCompressionMode(mode);
1340     }
1341 }
< prev index next >