mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-01 00:00:02 -04:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5da934e11b | |||
| 51297ad496 | |||
| 80a534cd62 | |||
| 24130d466d | |||
| 7559686782 | |||
| b6988c37a7 | |||
| bbffb1d416 | |||
| c68de3bc92 | |||
| a12b6044c6 | |||
| 9a0e2d9659 | |||
| b904f8952f | |||
| 187c952b8e | |||
| ca86605923 | |||
| 8bc863298f | |||
| 3447d1782c | |||
| bf245fde5f | |||
| c0748dcfd7 | |||
| c293516201 | |||
| f6dae36b7e | |||
| a14b481e9e | |||
| d9c1a39c37 | |||
| e9d9f99bb0 | |||
| b9749b94b0 | |||
| 4996dff6e4 | |||
| b1a2244c7f | |||
| c6fe747ca3 | |||
| e1af4d7da9 | |||
| 33556cc0ec | |||
| eaf13b102f | |||
| 74718f1ffb | |||
| bd3700ea59 | |||
| 8fccd9445f | |||
| cf0ed8f95c | |||
| c12e4e5646 | |||
| 287b73c732 | |||
| 24271b8cad | |||
| 3e2f54ee7c | |||
| 2511b2d0cd | |||
| a15d54c92c | |||
| 47b7c4b16c | |||
| 9e1b01a7fd | |||
| 769acc8726 | |||
| 1ace3a6d5f | |||
| a06eb53cd2 | |||
| 1e1a640a6c | |||
| 2444bc5ad4 | |||
| 2e656a45f9 | |||
| 657928f4a5 | |||
| 08f7e070dc | |||
| b205226f0c | |||
| 821df11d90 | |||
| a62a838a0d | |||
| 75ff0f265f | |||
| 15c7cfe9a6 | |||
| 1286077b02 | |||
| 5757743db7 | |||
| fbaa13d48d | |||
| f12df442e9 | |||
| 0c0712ab30 | |||
| 9267842788 | |||
| bcffeb04ec | |||
| d1a1bab18c | |||
| 6b5e75a22b |
@@ -1,15 +1,13 @@
|
||||
## Latest
|
||||
|
||||
Master branch build status: [](https://travis-ci.org/haraldk/TwelveMonkeys)
|
||||
|
||||
Latest release is TwelveMonkeys ImageIO [3.5](https://search.maven.org/search?q=g:com.twelvemonkeys.imageio%20AND%20v:3.5) (Jan. 22nd, 2020).
|
||||
[Release notes](https://github.com/haraldk/TwelveMonkeys/releases/latest).
|
||||
[](https://travis-ci.org/haraldk/TwelveMonkeys)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.twelvemonkeys.imageio/imageio)
|
||||
[](https://stackoverflow.com/questions/tagged/twelvemonkeys)
|
||||
[](https://paypal.me/haraldk76/100)
|
||||
|
||||
## About
|
||||
|
||||
TwelveMonkeys ImageIO is a collection of plugins and extensions for Java's ImageIO.
|
||||
|
||||
These plugins extends the number of image file formats supported in Java, using the javax.imageio.* package.
|
||||
These plugins extend the number of image file formats supported in Java, using the `javax.imageio.*` package.
|
||||
The main purpose of this project is to provide support for formats not covered by the JRE itself.
|
||||
|
||||
Support for formats is important, both to be able to read data found
|
||||
@@ -19,246 +17,58 @@ The goal is to create a set of efficient and robust ImageIO plug-ins, that can b
|
||||
|
||||
----
|
||||
|
||||
## Features
|
||||
## File formats supported
|
||||
|
||||
Mainstream format support
|
||||
| Plugin | Format | Description | Read | Write | Metadata | Notes |
|
||||
| ------ | -------- | ----------- |:----:|:-----:| -------- | ----- |
|
||||
| Batik | **SVG** | Scalable Vector Graphics | âś” | - | - | Requires [Batik](https://xmlgraphics.apache.org/batik/)
|
||||
| | WMF | MS Windows Metafile | âś” | - | - | Requires [Batik](https://xmlgraphics.apache.org/batik/)
|
||||
| [BMP](https://github.com/haraldk/TwelveMonkeys/wiki/BMP-Plugin) | **BMP** | MS Windows and IBM OS/2 Device Independent Bitmap | âś” | âś” | Native & Standard |
|
||||
| | CUR | MS Windows Cursor Format | âś” | - | - |
|
||||
| | ICO | MS Windows Icon Format | âś” | âś” | - |
|
||||
| [HDR](https://github.com/haraldk/TwelveMonkeys/wiki/HDR-Plugin) | HDR | Radiance High Dynamic Range RGBE Format | âś” | - | Standard |
|
||||
| [ICNS](https://github.com/haraldk/TwelveMonkeys/wiki/ICNS-Plugin) | ICNS | Apple Icon Image | âś” | âś” | - |
|
||||
| [IFF](https://github.com/haraldk/TwelveMonkeys/wiki/IFF-Plugin) | IFF | Commodore Amiga/Electronic Arts Interchange File Format | âś” | âś” | - |
|
||||
| [JPEG](https://github.com/haraldk/TwelveMonkeys/wiki/JPEG-Plugin) | **JPEG** | Joint Photographers Expert Group | âś” | âś” | Native & Standard |
|
||||
| [PCX](https://github.com/haraldk/TwelveMonkeys/wiki/PCX-Plugin) | PCX | ZSoft Paintbrush Format | âś” | - | Standard |
|
||||
| | DCX | Multi-page PCX fax document | âś” | - | Standard |
|
||||
| [PICT](https://github.com/haraldk/TwelveMonkeys/wiki/PICT-Plugin) | PICT | Apple Mac Paint Picture Format | âś” | - | - |
|
||||
| [PNM](https://github.com/haraldk/TwelveMonkeys/wiki/PNM-Plugin) | PAM | NetPBM Portable Any Map | âś” | âś” | Standard |
|
||||
| | PBM | NetPBM Portable Bit Map | âś” | - | Standard |
|
||||
| | PGM | NetPBM Portable Grey Map | âś” | - | Standard |
|
||||
| | PPM | NetPBM Portable Pix Map | âś” | âś” | Standard |
|
||||
| | PFM | Portable Float Map | âś” | - | Standard |
|
||||
| [PSD](https://github.com/haraldk/TwelveMonkeys/wiki/PSD-Plugin) | **PSD** | Adobe Photoshop Document | âś” | - | Native & Standard |
|
||||
| | PSB | Adobe Photoshop Large Document | âś” | - | Native & Standard |
|
||||
| [SGI](https://github.com/haraldk/TwelveMonkeys/wiki/SGI-Plugin) | SGI | Silicon Graphics Image Format | âś” | - | Standard |
|
||||
| [TGA](https://github.com/haraldk/TwelveMonkeys/wiki/TGA-Plugin) | TGA | Truevision TGA Image Format | âś” | âś” | Standard |
|
||||
|ThumbsDB| Thumbs.db| MS Windows Thumbs DB | âś” | - | - | OLE2 Compound Document based format only
|
||||
| [TIFF](https://github.com/haraldk/TwelveMonkeys/wiki/TIFF-Plugin) | **TIFF** | Aldus/Adobe Tagged Image File Format | âś” | âś” | Native & Standard |
|
||||
| | BigTIFF | | âś” | - | Native & Standard |
|
||||
| [WebP](https://github.com/haraldk/TwelveMonkeys/wiki/WebP-Plugin) | **WebP** | Google WebP Format | âś” | - | Standard | In progress
|
||||
| XWD | XWD | X11 Window Dump Format | âś” | - | Standard |
|
||||
|
||||
#### BMP - MS Windows/IBM OS/2 Device Independent Bitmap
|
||||
|
||||
* Read support for all known versions of the DIB/BMP format
|
||||
* Indexed color, 1, 4 and 8 bit, including 4 and 8 bit RLE
|
||||
* RGB, 16, 24 and 32 bit
|
||||
* Embedded PNG and JPEG data
|
||||
* Windows and OS/2 versions
|
||||
* Native and standard metadata format
|
||||
|
||||
#### JPEG
|
||||
|
||||
* Read support for the following JPEG "flavors":
|
||||
* All JFIF compliant JPEGs
|
||||
* All Exif compliant JPEGs
|
||||
* YCbCr JPEGs without JFIF segment (converted to RGB, using embedded ICC profile)
|
||||
* CMYK JPEGs (converted to RGB by default or as CMYK, using embedded ICC profile)
|
||||
* Adobe YCCK JPEGs (converted to RGB by default or as CMYK, using embedded ICC profile)
|
||||
* JPEGs containing ICC profiles with interpretation other than 'Perceptual' or class other than 'Display'
|
||||
* JPEGs containing ICC profiles that are incompatible with stream data, corrupted ICC profiles or corrupted `ICC_PROFILE` segments
|
||||
* JPEGs using non-standard color spaces, unsupported by Java 2D
|
||||
* JPEGs with APP14/Adobe segments with length other than 14 bytes
|
||||
* 8 bit JPEGs with 16 bit DQT segments
|
||||
* Issues warnings instead of throwing exceptions in cases of corrupted or non-conformant data where ever the image
|
||||
data can still be read in a reasonable way
|
||||
* Thumbnail support:
|
||||
* JFIF thumbnails (even if stream contains "inconsistent metadata")
|
||||
* JFXX thumbnails (JPEG, Indexed and RGB)
|
||||
* EXIF thumbnails (JPEG, RGB and YCbCr)
|
||||
* Metadata support:
|
||||
* JPEG metadata in both standard and native formats (even if stream contains "inconsistent metadata")
|
||||
* `javax_imageio_jpeg_image_1.0` format (currently as native format, may change in the future)
|
||||
* Non-conforming combinations of JFIF, Exif and Adobe markers, using "unknown" segments in the
|
||||
"MarkerSequence" tag for the unsupported segments (for `javax_imageio_jpeg_image_1.0` format)
|
||||
* Extended write support:
|
||||
* CMYK JPEGs
|
||||
* YCCK JPEGs in progress
|
||||
|
||||
#### JPEG-2000
|
||||
|
||||
* Possibly coming in the future, pending some license issues.
|
||||
|
||||
If you are one of the authors, or know one of the authors and/or the current license holders of either the original
|
||||
jj2000 package or the JAI ImageIO project, please contact me (I've tried to get in touch in various ways,
|
||||
without success so far).
|
||||
|
||||
Alternatively, if you have or know of a JPEG-2000 implementation in Java with a suitable license, get in touch. :-)
|
||||
|
||||
#### PNM - NetPBM Portable Any Map
|
||||
|
||||
* Read support for the following file types:
|
||||
* PBM in 'P1' (ASCII) and 'P4' (binary) formats, 1 bit per pixel
|
||||
* PGM in 'P2' (ASCII) and 'P5' (binary) formats, up to 16/32 bits per pixel
|
||||
* PPM in 'P3' (ASCII) and 'P6' (binary) formats, up to 16/32 bits per pixel component
|
||||
* PAM in 'P7' (binary) format up to 32 bits per pixel component
|
||||
* Limited support for PFM in 'Pf' (gray) and 'PF' (RGB) formats, 32 bits floating point
|
||||
* Write support for the following formats:
|
||||
* PPM in 'P6' (binary) format
|
||||
* PAM in 'P7' (binary) format
|
||||
* Standard metadata support
|
||||
|
||||
#### PSD - Adobe Photoshop Document
|
||||
|
||||
* Read support for the following file types:
|
||||
* Monochrome, 1 channel, 1 bit
|
||||
* Indexed, 1 channel, 8 bit
|
||||
* Gray, 1 channel, 8, 16 and 32 bit
|
||||
* Duotone, 1 channel, 8, 16 and 32 bit
|
||||
* RGB, 3-4 channels, 8, 16 and 32 bit
|
||||
* CMYK, 4-5 channels, 8, 16 and 32 bit
|
||||
* Read support for the following compression types:
|
||||
* Uncompressed
|
||||
* RLE (PackBits)
|
||||
* Layer support
|
||||
* Image layers only, in all of the above types
|
||||
* Thumbnail support
|
||||
* JPEG
|
||||
* RAW (RGB)
|
||||
* Support for "Large Document Format" (PSB)
|
||||
* Native and Standard metadata support
|
||||
|
||||
#### TIFF - Aldus/Adobe Tagged Image File Format
|
||||
|
||||
* Read support for the following "Baseline" TIFF file types:
|
||||
* Class B (Bi-level), all relevant compression types, 1 bit per sample
|
||||
* Class G (Gray), all relevant compression types, 2, 4, 8, 16 or 32 bits per sample, unsigned integer
|
||||
* Class P (Palette/indexed color), all relevant compression types, 1, 2, 4, 8 or 16 bits per sample, unsigned integer
|
||||
* Class R (RGB), all relevant compression types, 8 or 16 bits per sample, unsigned integer
|
||||
* Read support for the following TIFF extensions:
|
||||
* Tiling
|
||||
* Class F (Facsimile), CCITT Modified Huffman RLE, T4 and T6 (type 2, 3 and 4) compressions.
|
||||
* LZW Compression (type 5)
|
||||
* "Old-style" JPEG Compression (type 6), as a best effort, as the spec is not well-defined
|
||||
* JPEG Compression (type 7)
|
||||
* ZLib (aka Adobe-style Deflate) Compression (type 8)
|
||||
* Deflate Compression (type 32946)
|
||||
* Horizontal differencing Predictor (type 2) for LZW, ZLib, Deflate and PackBits compression
|
||||
* Alpha channel (ExtraSamples type 1/Associated Alpha and type 2/Unassociated Alpha)
|
||||
* CMYK data (PhotometricInterpretation type 5/Separated)
|
||||
* YCbCr data (PhotometricInterpretation type 6/YCbCr) for JPEG
|
||||
* CIELab data in TIFF, ITU and ICC variants (PhotometricInterpretation type 9, 10 and 11)
|
||||
* Planar data (PlanarConfiguration type 2/Planar)
|
||||
* ICC profiles (ICCProfile)
|
||||
* BitsPerSample values up to 16 for most PhotometricInterpretations
|
||||
* Multiple images (pages) in one file
|
||||
* Write support for most "Baseline" TIFF options
|
||||
* Uncompressed, PackBits, ZLib and Deflate
|
||||
* Additional support for CCITT T4 and and T6 compressions.
|
||||
* Additional support for LZW and JPEG (type 7) compressions
|
||||
* Horizontal differencing Predictor (type 2) for LZW, ZLib, Deflate
|
||||
* Native and Standard metadata support
|
||||
|
||||
Legacy formats
|
||||
|
||||
#### HDR - Radiance High Dynamic Range RGBE Format
|
||||
|
||||
* Read support for the most common RGBE (.hdr) format
|
||||
* Samples are converted to 32 bit floating point (`float`) and normalized using a global tone mapper by default.
|
||||
* Support for custom global tone mappers
|
||||
* Alternatively, use a "null-tone mapper", for unnormalized data (allows local tone mapping)
|
||||
* Unconverted RGBE samples accessible using `readRaster`
|
||||
* Standard metadata support
|
||||
|
||||
#### IFF - Commodore Amiga/Electronic Arts Interchange File Format
|
||||
|
||||
* Legacy format, allows reading popular image format from the Commodore Amiga computer.
|
||||
* Read support for the following file types:
|
||||
* ILBM Indexed color, 1-8 interleaved bit planes, including 6 bit EHB
|
||||
* ILBM Gray, 8 bit interleaved bit planes
|
||||
* ILBM RGB, 24 and 32 bit interleaved bit planes
|
||||
* ILBM HAM6 and HAM8
|
||||
* PBM Indexed color, 1-8 bit,
|
||||
* PBM Gray, 8 bit
|
||||
* PBM RGB, 24 and 32 bit
|
||||
* PBM HAM6 and HAM8
|
||||
* Write support
|
||||
* ILBM Indexed color, 1-8 bits per sample, 8 bit gray, 24 and 32 bit true color.
|
||||
* Support for the following compression types (read/write):
|
||||
* Uncompressed
|
||||
* RLE (PackBits)
|
||||
|
||||
#### PCX - ZSoft Paintbrush Format
|
||||
|
||||
* Read support for the following file types:
|
||||
* Indexed color, 1, 2, 4 or 8 bits per pixel, bit planes or interleaved
|
||||
* Grayscale, 8 bits per pixel
|
||||
* Color (RGB), 8 bits per pixel component
|
||||
* Read support for DCX (multi-page) fax format, containing any of the above types
|
||||
* Support for the following compression types:
|
||||
* Uncompressed (experimental)
|
||||
* RLE compressed
|
||||
* Standard metadata support
|
||||
|
||||
#### PICT - Apple Mac Paint Picture Format
|
||||
|
||||
* Legacy format, especially useful for reading OS X clipboard data.
|
||||
* Read support for the following file types:
|
||||
* QuickDraw (format support is not complete, but supports most OS X clipboard data as well as RGB pixel data)
|
||||
* QuickDraw bitmap
|
||||
* QuickDraw pixmap
|
||||
* QuickTime stills
|
||||
* Write support for RGB pixel data:
|
||||
* QuickDraw pixmap
|
||||
|
||||
#### SGI - Silicon Graphics Image Format
|
||||
|
||||
* Read support for the following file types:
|
||||
* 1, 2, 3 or 4 channel image data
|
||||
* 8 or 16 bits per pixel component
|
||||
* Support for the following compression types:
|
||||
* Uncompressed
|
||||
* RLE compressed
|
||||
* Standard metadata support
|
||||
|
||||
#### TGA - Truevision TGA Image Format
|
||||
|
||||
* Read support for the following file types:
|
||||
* ColorMapped
|
||||
* Monochrome
|
||||
* TrueColor
|
||||
* Support for the following compression types:
|
||||
* Uncompressed
|
||||
* RLE compressed
|
||||
* Standard metadata support
|
||||
* Write support
|
||||
|
||||
Icon/other formats
|
||||
|
||||
#### ICNS - Apple Icon Image
|
||||
|
||||
* Read support for the following icon types:
|
||||
* All known "native" icon types
|
||||
* Large PNG encoded icons
|
||||
* Large JPEG 2000 encoded icons (requires JPEG 2000 ImageIO plugin or fallback to `sips` command line tool)
|
||||
* Write support for PNG encoded icons
|
||||
|
||||
#### ICO & CUR - MS Windows Icon and Cursor Formats
|
||||
|
||||
* Read support for the following file types:
|
||||
* ICO Indexed color, 1, 4 and 8 bit
|
||||
* ICO RGB, 16, 24 and 32 bit
|
||||
* CUR Indexed color, 1, 4 and 8 bit
|
||||
* CUR RGB, 16, 24 and 32 bit
|
||||
* Write support
|
||||
* *3.1* Note: These formats are now part of the BMP plugin
|
||||
|
||||
#### Thumbs.db - MS Windows Thumbs DB
|
||||
|
||||
* Read support
|
||||
|
||||
Other formats, using 3rd party libraries
|
||||
|
||||
#### SVG - Scalable Vector Graphics
|
||||
|
||||
* Read-only support using Batik
|
||||
|
||||
#### WMF - MS Windows MetaFile
|
||||
|
||||
* Limited read-only support using Batik
|
||||
|
||||
**Important note on using Batik:** *Please read [The Apache™ XML Graphics Project - Security](http://xmlgraphics.apache.org/security.html), and make sure you use
|
||||
either version 1.6.1, 1.7.1 or 1.8+.*
|
||||
|
||||
**Important note on using Batik:** *Please read [The Apache™ XML Graphics Project - Security](http://xmlgraphics.apache.org/security.html),
|
||||
and make sure you use either version 1.6.1, 1.7.1, 1.8+ or later.*
|
||||
|
||||
## Basic usage
|
||||
|
||||
Most of the time, all you need to do is simply include the plugins in your project and write:
|
||||
|
||||
BufferedImage image = ImageIO.read(file);
|
||||
```java
|
||||
BufferedImage image = ImageIO.read(file);
|
||||
```
|
||||
|
||||
This will load the first image of the file, entirely into memory.
|
||||
|
||||
The basic and simplest form of writing is:
|
||||
|
||||
if (!ImageIO.write(image, format, file)) {
|
||||
// Handle image not written case
|
||||
}
|
||||
```java
|
||||
if (!ImageIO.write(image, format, file)) {
|
||||
// Handle image not written case
|
||||
}
|
||||
```
|
||||
|
||||
This will write the entire image into a single file, using the default settings for the given format.
|
||||
|
||||
@@ -269,50 +79,50 @@ The plugins are discovered automatically at run time. See the [FAQ](#faq) for mo
|
||||
If you need more control of read parameters and the reading process, the common idiom for reading is something like:
|
||||
|
||||
```java
|
||||
// Create input stream
|
||||
ImageInputStream input = ImageIO.createImageInputStream(file);
|
||||
// Create input stream
|
||||
ImageInputStream input = ImageIO.createImageInputStream(file);
|
||||
|
||||
try {
|
||||
// Get the reader
|
||||
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
|
||||
|
||||
if (!readers.hasNext()) {
|
||||
throw new IllegalArgumentException("No reader for: " + file);
|
||||
}
|
||||
|
||||
ImageReader reader = readers.next();
|
||||
|
||||
try {
|
||||
// Get the reader
|
||||
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
|
||||
reader.setInput(input);
|
||||
|
||||
if (!readers.hasNext()) {
|
||||
throw new IllegalArgumentException("No reader for: " + file);
|
||||
}
|
||||
// Optionally, listen for read warnings, progress, etc.
|
||||
reader.addIIOReadWarningListener(...);
|
||||
reader.addIIOReadProgressListener(...);
|
||||
|
||||
ImageReader reader = readers.next();
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
|
||||
try {
|
||||
reader.setInput(input);
|
||||
// Optionally, control read settings like sub sampling, source region or destination etc.
|
||||
param.setSourceSubsampling(...);
|
||||
param.setSourceRegion(...);
|
||||
param.setDestination(...);
|
||||
// ...
|
||||
|
||||
// Optionally, listen for read warnings, progress, etc.
|
||||
reader.addIIOReadWarningListener(...);
|
||||
reader.addIIOReadProgressListener(...);
|
||||
// Finally read the image, using settings from param
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
|
||||
// Optionally, control read settings like sub sampling, source region or destination etc.
|
||||
param.setSourceSubsampling(...);
|
||||
param.setSourceRegion(...);
|
||||
param.setDestination(...);
|
||||
// ...
|
||||
|
||||
// Finally read the image, using settings from param
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
// Optionally, read thumbnails, meta data, etc...
|
||||
int numThumbs = reader.getNumThumbnails(0);
|
||||
// ...
|
||||
}
|
||||
finally {
|
||||
// Dispose reader in finally block to avoid memory leaks
|
||||
reader.dispose();
|
||||
}
|
||||
// Optionally, read thumbnails, meta data, etc...
|
||||
int numThumbs = reader.getNumThumbnails(0);
|
||||
// ...
|
||||
}
|
||||
finally {
|
||||
// Close stream in finally block to avoid resource leaks
|
||||
input.close();
|
||||
// Dispose reader in finally block to avoid memory leaks
|
||||
reader.dispose();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// Close stream in finally block to avoid resource leaks
|
||||
input.close();
|
||||
}
|
||||
```
|
||||
|
||||
Query the reader for source image dimensions using `reader.getWidth(n)` and `reader.getHeight(n)` without reading the
|
||||
@@ -324,86 +134,62 @@ It's also possible to read multiple images from the same file in a loop, using `
|
||||
If you need more control of write parameters and the writing process, the common idiom for writing is something like:
|
||||
|
||||
```java
|
||||
// Get the writer
|
||||
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(format);
|
||||
// Get the writer
|
||||
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(format);
|
||||
|
||||
if (!writers.hasNext()) {
|
||||
throw new IllegalArgumentException("No writer for: " + format);
|
||||
}
|
||||
if (!writers.hasNext()) {
|
||||
throw new IllegalArgumentException("No writer for: " + format);
|
||||
}
|
||||
|
||||
ImageWriter writer = writers.next();
|
||||
ImageWriter writer = writers.next();
|
||||
|
||||
try {
|
||||
// Create output stream
|
||||
ImageOutputStream output = ImageIO.createImageOutputStream(file);
|
||||
|
||||
try {
|
||||
// Create output stream
|
||||
ImageOutputStream output = ImageIO.createImageOutputStream(file);
|
||||
writer.setOutput(output);
|
||||
|
||||
try {
|
||||
writer.setOutput(output);
|
||||
// Optionally, listen to progress, warnings, etc.
|
||||
|
||||
// Optionally, listen to progress, warnings, etc.
|
||||
ImageWriteParam param = writer.getDefaultWriteParam();
|
||||
|
||||
ImageWriteParam param = writer.getDefaultWriteParam();
|
||||
// Optionally, control format specific settings of param (requires casting), or
|
||||
// control generic write settings like sub sampling, source region, output type etc.
|
||||
|
||||
// Optionally, control format specific settings of param (requires casting), or
|
||||
// control generic write settings like sub sampling, source region, output type etc.
|
||||
|
||||
// Optionally, provide thumbnails and image/stream metadata
|
||||
writer.write(..., new IIOImage(..., image, ...), param);
|
||||
}
|
||||
finally {
|
||||
// Close stream in finally block to avoid resource leaks
|
||||
output.close();
|
||||
}
|
||||
// Optionally, provide thumbnails and image/stream metadata
|
||||
writer.write(..., new IIOImage(..., image, ...), param);
|
||||
}
|
||||
finally {
|
||||
// Dispose writer in finally block to avoid memory leaks
|
||||
writer.dispose();
|
||||
// Close stream in finally block to avoid resource leaks
|
||||
output.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// Dispose writer in finally block to avoid memory leaks
|
||||
writer.dispose();
|
||||
}
|
||||
```
|
||||
|
||||
For more advanced usage, and information on how to use the ImageIO API, I suggest you read the
|
||||
[Java Image I/O API Guide](http://docs.oracle.com/javase/7/docs/technotes/guides/imageio/spec/imageio_guideTOC.fm.html)
|
||||
from Oracle.
|
||||
|
||||
#### Adobe Clipping Path support
|
||||
|
||||
#### Deploying the plugins in a web app
|
||||
```java
|
||||
import com.twelvemonkeys.imageio.path.Paths;
|
||||
|
||||
Because the `ImageIO` plugin registry (the `IIORegistry`) is "VM global", it doesn't by default work well with
|
||||
servlet contexts. This is especially evident if you load plugins from the `WEB-INF/lib` or `classes` folder.
|
||||
Unless you add `ImageIO.scanForPlugins()` somewhere in your code, the plugins might never be available at all.
|
||||
...
|
||||
|
||||
In addition, servlet contexts dynamically loads and unloads classes (using a new class loader per context).
|
||||
If you restart your application, old classes will by default remain in memory forever (because the next time
|
||||
`scanForPlugins` is called, it's another `ClassLoader` that scans/loads classes, and thus they will be new instances
|
||||
in the registry). If a read is attempted using one of the remaining "old" readers, weird exceptions
|
||||
(like `NullPointerException`s when accessing `static final` initialized fields or `NoClassDefFoundError`s
|
||||
for uninitialized inner classes) may occur.
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(new File("image_with_path.jpg")) {
|
||||
BufferedImage image = Paths.readClipped(stream);
|
||||
|
||||
To work around both the discovery problem and the resource leak,
|
||||
it is *strongly recommended* to use the `IIOProviderContextListener` that implements
|
||||
dynamic loading and unloading of ImageIO plugins for web applications.
|
||||
|
||||
```xml
|
||||
<web-app ...>
|
||||
|
||||
...
|
||||
|
||||
<listener>
|
||||
<display-name>ImageIO service provider loader/unloader</display-name>
|
||||
<listener-class>com.twelvemonkeys.servlet.image.IIOProviderContextListener</listener-class>
|
||||
</listener>
|
||||
|
||||
...
|
||||
|
||||
</web-app>
|
||||
// Do something with the clipped image...
|
||||
}
|
||||
```
|
||||
See [Adobe Clipping Path support on the Wiki](https://github.com/haraldk/TwelveMonkeys/wiki/Photoshop-Clipping-Path-support) for more details and example code.
|
||||
|
||||
Loading plugins from `WEB-INF/lib` without the context listener installed is unsupported and will not work correctly.
|
||||
|
||||
The context listener has no dependencies to the TwelveMonkeys ImageIO plugins, and may be used with JAI ImageIO
|
||||
or other ImageIO plugins as well.
|
||||
|
||||
Another safe option, is to place the JAR files in the application server's shared or common lib folder.
|
||||
|
||||
#### Using the ResampleOp
|
||||
|
||||
@@ -411,15 +197,15 @@ The library comes with a resampling (image resizing) operation, that contains ma
|
||||
to provide excellent results at reasonable speed.
|
||||
|
||||
```java
|
||||
import com.twelvemonkeys.image.ResampleOp;
|
||||
import com.twelvemonkeys.image.ResampleOp;
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
BufferedImage input = ...; // Image to resample
|
||||
int width, height = ...; // new width/height
|
||||
BufferedImage input = ...; // Image to resample
|
||||
int width, height = ...; // new width/height
|
||||
|
||||
BufferedImageOp resampler = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS); // A good default filter, see class documentation for more info
|
||||
BufferedImage output = resampler.filter(input, null);
|
||||
BufferedImageOp resampler = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS); // A good default filter, see class documentation for more info
|
||||
BufferedImage output = resampler.filter(input, null);
|
||||
```
|
||||
|
||||
#### Using the DiffusionDither
|
||||
@@ -428,14 +214,14 @@ The library comes with a dithering operation, that can be used to convert `Buffe
|
||||
Floyd-Steinberg error-diffusion dither.
|
||||
|
||||
```java
|
||||
import com.twelvemonkeys.image.DiffusionDither;
|
||||
import com.twelvemonkeys.image.DiffusionDither;
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
BufferedImage input = ...; // Image to dither
|
||||
BufferedImage input = ...; // Image to dither
|
||||
|
||||
BufferedImageOp ditherer = new DiffusionDither();
|
||||
BufferedImage output = ditherer.filter(input, null);
|
||||
BufferedImageOp ditherer = new DiffusionDither();
|
||||
BufferedImage output = ditherer.filter(input, null);
|
||||
```
|
||||
|
||||
## Building
|
||||
@@ -473,10 +259,10 @@ The ImageIO registry and service lookup mechanism will make sure the plugins are
|
||||
To verify that the JPEG plugin is installed and used at run-time, you could use the following code:
|
||||
|
||||
```java
|
||||
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
|
||||
while (readers.hasNext()) {
|
||||
System.out.println("reader: " + readers.next());
|
||||
}
|
||||
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
|
||||
while (readers.hasNext()) {
|
||||
System.out.println("reader: " + readers.next());
|
||||
}
|
||||
```
|
||||
|
||||
The first line should print:
|
||||
@@ -488,82 +274,144 @@ The first line should print:
|
||||
To depend on the JPEG and TIFF plugin using Maven, add the following to your POM:
|
||||
|
||||
```xml
|
||||
...
|
||||
<dependencies>
|
||||
...
|
||||
<dependencies>
|
||||
...
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
<version>3.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-tiff</artifactId>
|
||||
<version>3.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-tiff</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Optional dependency. Needed only if you deploy `ImageIO` plugins as part of a web app.
|
||||
Make sure you add the `IIOProviderContextListener` to your `web.xml`, see above.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.servlet</groupId>
|
||||
<artifactId>servlet</artifactId>
|
||||
<version>3.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!--
|
||||
Optional dependency. Needed only if you deploy `ImageIO` plugins as part of a web app.
|
||||
Make sure you add the `IIOProviderContextListener` to your `web.xml`, see above.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.servlet</groupId>
|
||||
<artifactId>servlet</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
#### Manual dependency example
|
||||
|
||||
To depend on the JPEG and TIFF plugin in your IDE or program, add all of the following JARs to your class path:
|
||||
|
||||
twelvemonkeys-common-lang-3.5.jar
|
||||
twelvemonkeys-common-io-3.5.jar
|
||||
twelvemonkeys-common-image-3.5.jar
|
||||
twelvemonkeys-imageio-core-3.5.jar
|
||||
twelvemonkeys-imageio-metadata-3.5.jar
|
||||
twelvemonkeys-imageio-jpeg-3.5.jar
|
||||
twelvemonkeys-imageio-tiff-3.5.jar
|
||||
twelvemonkeys-common-lang-3.6.1.jar
|
||||
twelvemonkeys-common-io-3.6.1.jar
|
||||
twelvemonkeys-common-image-3.6.1.jar
|
||||
twelvemonkeys-imageio-core-3.6.1.jar
|
||||
twelvemonkeys-imageio-metadata-3.6.1.jar
|
||||
twelvemonkeys-imageio-jpeg-3.6.1.jar
|
||||
twelvemonkeys-imageio-tiff-3.6.1.jar
|
||||
|
||||
#### Deploying the plugins in a web app
|
||||
|
||||
Because the `ImageIO` plugin registry (the `IIORegistry`) is "VM global", it doesn't by default work well with
|
||||
servlet contexts. This is especially evident if you load plugins from the `WEB-INF/lib` or `classes` folder.
|
||||
Unless you add `ImageIO.scanForPlugins()` somewhere in your code, the plugins might never be available at all.
|
||||
|
||||
In addition, servlet contexts dynamically loads and unloads classes (using a new class loader per context).
|
||||
If you restart your application, old classes will by default remain in memory forever (because the next time
|
||||
`scanForPlugins` is called, it's another `ClassLoader` that scans/loads classes, and thus they will be new instances
|
||||
in the registry). If a read is attempted using one of the remaining "old" readers, weird exceptions
|
||||
(like `NullPointerException`s when accessing `static final` initialized fields or `NoClassDefFoundError`s
|
||||
for uninitialized inner classes) may occur.
|
||||
|
||||
To work around both the discovery problem and the resource leak,
|
||||
it is *strongly recommended* to use the `IIOProviderContextListener` that implements
|
||||
dynamic loading and unloading of ImageIO plugins for web applications.
|
||||
|
||||
```xml
|
||||
<web-app ...>
|
||||
|
||||
...
|
||||
|
||||
<listener>
|
||||
<display-name>ImageIO service provider loader/unloader</display-name>
|
||||
<listener-class>com.twelvemonkeys.servlet.image.IIOProviderContextListener</listener-class>
|
||||
</listener>
|
||||
|
||||
...
|
||||
|
||||
</web-app>
|
||||
```
|
||||
|
||||
Loading plugins from `WEB-INF/lib` without the context listener installed is unsupported and will not work correctly.
|
||||
|
||||
The context listener has no dependencies to the TwelveMonkeys ImageIO plugins, and may be used with JAI ImageIO
|
||||
or other ImageIO plugins as well.
|
||||
|
||||
Another safe option, is to place the JAR files in the application server's shared or common lib folder.
|
||||
|
||||
#### Including the plugins in a "fat" JAR
|
||||
|
||||
The recommended way to use the plugins, is just to include the JARs as-is in your project, through a Maven dependency or similar.
|
||||
Re-packaging is not necessary to use the library, and not recommended.
|
||||
|
||||
However, if you like to create a "fat"
|
||||
JAR, or otherwise like to re-package the JARs for some reason, it's important to remember that automatic discovery of
|
||||
the plugins by ImageIO depends on the
|
||||
[Service Provider Interface (SPI)](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html) mechanism.
|
||||
In short, each JAR contains a special folder, named `META-INF/services` containing one or more files,
|
||||
typically `javax.imageio.spi.ImageReaderSpi` and `javax.imageio.spi.ImageWriterSpi`.
|
||||
These files exist *with the same name in every JAR*,
|
||||
so if you simply unpack everything to a single folder or create a JAR, files will be overwritten and behavior be
|
||||
unspecified (most likely you will end up with a single plugin being installed).
|
||||
|
||||
The solution is to make sure all files with the same name, are merged to a single file,
|
||||
containing all the SPI information of each type. If using the Maven Shade plugin, you should use the
|
||||
[ServicesResourceTransformer](https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#ServicesResourceTransformer)
|
||||
to properly merge these files. You may also want to use the
|
||||
[ManifestResourceTransforme](https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#ManifestResourceTransformer)
|
||||
to get the correct vendor name, version info etc.
|
||||
Other "fat" JAR bundlers will probably have similar mechanisms to merge entries with the same name.
|
||||
|
||||
### Links to prebuilt binaries
|
||||
|
||||
##### Latest version (3.5)
|
||||
##### Latest version (3.6.1)
|
||||
|
||||
Requires Java 7 or later.
|
||||
|
||||
Common dependencies
|
||||
* [common-lang-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.5/common-lang-3.5.jar)
|
||||
* [common-io-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.5/common-io-3.5.jar)
|
||||
* [common-image-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.5/common-image-3.5.jar)
|
||||
* [common-lang-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.6.1/common-lang-3.6.1.jar)
|
||||
* [common-io-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.6.1/common-io-3.6.1.jar)
|
||||
* [common-image-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.6.1/common-image-3.6.1.jar)
|
||||
|
||||
ImageIO dependencies
|
||||
* [imageio-core-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.5/imageio-core-3.5.jar)
|
||||
* [imageio-metadata-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.5/imageio-metadata-3.5.jar)
|
||||
* [imageio-core-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.6.1/imageio-core-3.6.1.jar)
|
||||
* [imageio-metadata-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.6.1/imageio-metadata-3.6.1.jar)
|
||||
|
||||
ImageIO plugins
|
||||
* [imageio-bmp-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-bmp/3.5/imageio-bmp-3.5.jar)
|
||||
* [imageio-jpeg-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.5/imageio-jpeg-3.5.jar)
|
||||
* [imageio-tiff-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.5/imageio-tiff-3.5.jar)
|
||||
* [imageio-pnm-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pnm/3.5/imageio-pnm-3.5.jar)
|
||||
* [imageio-psd-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.5/imageio-psd-3.5.jar)
|
||||
* [imageio-hdr-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-hdr/3.5/imageio-hdr-3.5.jar)
|
||||
* [imageio-iff-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.5/imageio-iff-3.5.jar)
|
||||
* [imageio-pcx-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pcx/3.5/imageio-pcx-3.5.jar)
|
||||
* [imageio-pict-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.5/imageio-pict-3.5.jar)
|
||||
* [imageio-sgi-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-sgi/3.5/imageio-sgi-3.5.jar)
|
||||
* [imageio-tga-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tga/3.5/imageio-tga-3.5.jar)
|
||||
* [imageio-icns-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.5/imageio-icns-3.5.jar)
|
||||
* [imageio-thumbsdb-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.5/imageio-thumbsdb-3.5.jar)
|
||||
* [imageio-bmp-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-bmp/3.6.1/imageio-bmp-3.6.1.jar)
|
||||
* [imageio-jpeg-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.6.1/imageio-jpeg-3.6.1.jar)
|
||||
* [imageio-tiff-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.6.1/imageio-tiff-3.6.1.jar)
|
||||
* [imageio-pnm-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pnm/3.6.1/imageio-pnm-3.6.1.jar)
|
||||
* [imageio-psd-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.6.1/imageio-psd-3.6.1.jar)
|
||||
* [imageio-hdr-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-hdr/3.6.1/imageio-hdr-3.6.1.jar)
|
||||
* [imageio-iff-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.6.1/imageio-iff-3.6.1.jar)
|
||||
* [imageio-pcx-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pcx/3.6.1/imageio-pcx-3.6.1.jar)
|
||||
* [imageio-pict-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.6.1/imageio-pict-3.6.1.jar)
|
||||
* [imageio-sgi-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-sgi/3.6.1/imageio-sgi-3.6.1.jar)
|
||||
* [imageio-tga-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tga/3.6.1/imageio-tga-3.6.1.jar)
|
||||
* [imageio-icns-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.6.1/imageio-icns-3.6.1.jar)
|
||||
* [imageio-thumbsdb-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.6.1/imageio-thumbsdb-3.6.1.jar)
|
||||
|
||||
ImageIO plugins requiring 3rd party libs
|
||||
* [imageio-batik-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.5/imageio-batik-3.5.jar)
|
||||
* [imageio-batik-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.6.1/imageio-batik-3.6.1.jar)
|
||||
|
||||
Photoshop Path support for ImageIO
|
||||
* [imageio-clippath-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-clippath/3.5/imageio-clippath-3.5.jar)
|
||||
* [imageio-clippath-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-clippath/3.6.1/imageio-clippath-3.6.1.jar)
|
||||
|
||||
Servlet support
|
||||
* [servlet-3.5.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.5/servlet-3.5.jar)
|
||||
* [servlet-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.6.1/servlet-3.6.1.jar)
|
||||
|
||||
##### Old version (3.0.x)
|
||||
|
||||
@@ -600,7 +448,7 @@ Servlet support
|
||||
|
||||
The project is distributed under the OSI approved [BSD license](http://opensource.org/licenses/BSD-3-Clause):
|
||||
|
||||
Copyright (c) 2008-2018, Harald Kuhr
|
||||
Copyright (c) 2008-2020, Harald Kuhr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+6
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys</groupId>
|
||||
<artifactId>twelvemonkeys</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.twelvemonkeys.bom</groupId>
|
||||
@@ -123,6 +123,11 @@
|
||||
<artifactId>imageio-tiff</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-xwd</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ImageIO 3rd party dependent plugins -->
|
||||
<dependency>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>common-image</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>common-io</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -72,7 +72,7 @@ public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte pBytes[], int pOffset, int pLength) {
|
||||
public void write(byte[] pBytes, int pOffset, int pLength) {
|
||||
if ((pOffset < 0) || (pOffset > pBytes.length) || (pLength < 0) ||
|
||||
((pOffset + pLength) > pBytes.length) || ((pOffset + pLength) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
@@ -98,7 +98,7 @@ public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
private void growIfNeeded(int pNewCount) {
|
||||
if (pNewCount > buf.length) {
|
||||
int newSize = Math.max(Math.min(buf.length << 1, buf.length + maxGrowSize), pNewCount);
|
||||
byte newBuf[] = new byte[newSize];
|
||||
byte[] newBuf = new byte[newSize];
|
||||
System.arraycopy(buf, 0, newBuf, 0, count);
|
||||
buf = newBuf;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
// Non-synchronized version of toByteArray
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
byte newBuf[] = new byte[count];
|
||||
byte[] newBuf = new byte[count];
|
||||
System.arraycopy(buf, 0, newBuf, 0, count);
|
||||
|
||||
return newBuf;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>common-lang</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys</groupId>
|
||||
<artifactId>twelvemonkeys</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
@@ -47,7 +47,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.7</version>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys</groupId>
|
||||
<artifactId>twelvemonkeys</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<groupId>com.twelvemonkeys.contrib</groupId>
|
||||
<artifactId>contrib</artifactId>
|
||||
@@ -65,7 +65,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.7</version>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -35,7 +35,7 @@ public class EXIFUtilities {
|
||||
* @throws IOException if an error occurs during reading.
|
||||
*/
|
||||
public static IIOImage readWithOrientation(final URL input) throws IOException {
|
||||
try (ImageInputStream stream = ImageIO.createImageOutputStream(input)) {
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(input)) {
|
||||
return readWithOrientation(stream);
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public class EXIFUtilities {
|
||||
* @throws IOException if an error occurs during reading.
|
||||
*/
|
||||
public static IIOImage readWithOrientation(final InputStream input) throws IOException {
|
||||
try (ImageInputStream stream = ImageIO.createImageOutputStream(input)) {
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(input)) {
|
||||
return readWithOrientation(stream);
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class EXIFUtilities {
|
||||
* @throws IOException if an error occurs during reading.
|
||||
*/
|
||||
public static IIOImage readWithOrientation(final File input) throws IOException {
|
||||
try (ImageInputStream stream = ImageIO.createImageOutputStream(input)) {
|
||||
try (ImageInputStream stream = ImageIO.createImageInputStream(input)) {
|
||||
return readWithOrientation(stream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-batik</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: Batik Plugin</name>
|
||||
@@ -39,6 +39,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+8
-20
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.svg;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -44,7 +45,6 @@ import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImagingOpException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
@@ -67,7 +67,10 @@ import static org.mockito.Mockito.*;
|
||||
*/
|
||||
public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader> {
|
||||
|
||||
private SVGImageReaderSpi provider = new SVGImageReaderSpi();
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new SVGImageReaderSpi();
|
||||
}
|
||||
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
@@ -82,19 +85,6 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
);
|
||||
}
|
||||
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SVGImageReader createReader() {
|
||||
return new SVGImageReader(createProvider());
|
||||
}
|
||||
|
||||
protected Class<SVGImageReader> getReaderClass() {
|
||||
return SVGImageReader.class;
|
||||
}
|
||||
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("svg");
|
||||
}
|
||||
@@ -111,8 +101,6 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
public void testScaleViewBox() throws IOException {
|
||||
URL svgUrl = getClassLoaderResource("/svg/quadrants.svg");
|
||||
|
||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
|
||||
SVGImageReader reader = createReader();
|
||||
SVGReadParam param = new SVGReadParam();
|
||||
|
||||
@@ -160,11 +148,11 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testReadWithSizeParam() {
|
||||
public void testReadWithSizeParam() throws IOException {
|
||||
try {
|
||||
super.testReadWithSizeParam();
|
||||
}
|
||||
catch (AssertionError failure) {
|
||||
catch (AssertionError | IOException failure) {
|
||||
Throwable cause = failure;
|
||||
|
||||
while (cause.getCause() != null) {
|
||||
@@ -299,7 +287,7 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
params.setAllowExternalResources(true);
|
||||
reader.read(0, params);
|
||||
|
||||
assertTrue("reader.read should've thrown an exception, but didn't", false);
|
||||
fail("reader.read should've thrown an exception, but didn't");
|
||||
}
|
||||
catch (IIOException allowed) {
|
||||
assertTrue(allowed.getMessage().contains("batikLogo.svg")); // The embedded resource we don't find
|
||||
|
||||
+7
-13
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.wmf;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -49,7 +50,10 @@ import java.util.List;
|
||||
* @version $Id: WMFImageReaderTest.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
|
||||
*/
|
||||
public class WMFImageReaderTest extends ImageReaderAbstractTest<WMFImageReader> {
|
||||
private WMFImageReaderSpi provider = new WMFImageReaderSpi();
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new WMFImageReaderSpi();
|
||||
}
|
||||
|
||||
protected List<TestData> getTestData() {
|
||||
return Collections.singletonList(
|
||||
@@ -57,27 +61,17 @@ public class WMFImageReaderTest extends ImageReaderAbstractTest<WMFImageReader>
|
||||
);
|
||||
}
|
||||
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WMFImageReader createReader() {
|
||||
return new WMFImageReader(createProvider());
|
||||
}
|
||||
|
||||
protected Class<WMFImageReader> getReaderClass() {
|
||||
return WMFImageReader.class;
|
||||
}
|
||||
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("wmf");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSuffixes() {
|
||||
return Arrays.asList("wmf", "emf");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getMIMETypes() {
|
||||
return Arrays.asList("image/x-wmf", "application/x-msmetafile");
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-bmp</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: BMP plugin</name>
|
||||
@@ -19,6 +19,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+67
-53
@@ -30,22 +30,6 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
||||
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
|
||||
import com.twelvemonkeys.io.LittleEndianDataInputStream;
|
||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||
import com.twelvemonkeys.xml.XMLSerializer;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.event.IIOReadUpdateListener;
|
||||
import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.*;
|
||||
@@ -56,6 +40,27 @@ import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.event.IIOReadUpdateListener;
|
||||
import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
||||
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
|
||||
import com.twelvemonkeys.io.LittleEndianDataInputStream;
|
||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||
import com.twelvemonkeys.xml.XMLSerializer;
|
||||
|
||||
/**
|
||||
* ImageReader for Microsoft Windows Bitmap (BMP) format.
|
||||
*
|
||||
@@ -125,6 +130,10 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
|
||||
// Read DIB header
|
||||
header = DIBHeader.read(imageInput);
|
||||
|
||||
if (pixelOffset < header.size + DIB.BMP_FILE_HEADER_SIZE) {
|
||||
throw new IIOException("Invalid pixel offset: " + pixelOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,50 +216,55 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
throw new IIOException("Multiple planes not supported");
|
||||
}
|
||||
|
||||
switch (header.getBitCount()) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
return ImageTypeSpecifiers.createFromIndexColorModel(readColorMap());
|
||||
try {
|
||||
switch (header.getBitCount()) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
return ImageTypeSpecifiers.createFromIndexColorModel(readColorMap());
|
||||
|
||||
case 16:
|
||||
if (header.hasMasks()) {
|
||||
return ImageTypeSpecifiers.createPacked(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
||||
DataBuffer.TYPE_USHORT, false
|
||||
);
|
||||
}
|
||||
case 16:
|
||||
if (header.hasMasks()) {
|
||||
return ImageTypeSpecifiers.createPacked(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
||||
DataBuffer.TYPE_USHORT, false
|
||||
);
|
||||
}
|
||||
|
||||
// Default if no mask is 555
|
||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_555_RGB);
|
||||
// Default if no mask is 555
|
||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_555_RGB);
|
||||
|
||||
case 24:
|
||||
if (header.getCompression() != DIB.COMPRESSION_RGB) {
|
||||
throw new IIOException("Unsupported compression for RGB: " + header.getCompression());
|
||||
}
|
||||
case 24:
|
||||
if (header.getCompression() != DIB.COMPRESSION_RGB) {
|
||||
throw new IIOException("Unsupported compression for RGB: " + header.getCompression());
|
||||
}
|
||||
|
||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR);
|
||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR);
|
||||
|
||||
case 32:
|
||||
if (header.hasMasks()) {
|
||||
return ImageTypeSpecifiers.createPacked(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
||||
DataBuffer.TYPE_INT, false
|
||||
);
|
||||
}
|
||||
case 32:
|
||||
if (header.hasMasks()) {
|
||||
return ImageTypeSpecifiers.createPacked(
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
||||
DataBuffer.TYPE_INT, false
|
||||
);
|
||||
}
|
||||
|
||||
// Default if no mask
|
||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
|
||||
// Default if no mask
|
||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
case 0:
|
||||
if (header.getCompression() == DIB.COMPRESSION_JPEG || header.getCompression() == DIB.COMPRESSION_PNG) {
|
||||
return initReaderDelegate(header.getCompression()).getRawImageType(0);
|
||||
}
|
||||
default:
|
||||
throw new IIOException("Unsupported bit count: " + header.getBitCount());
|
||||
case 0:
|
||||
if (header.getCompression() == DIB.COMPRESSION_JPEG || header.getCompression() == DIB.COMPRESSION_PNG) {
|
||||
return initReaderDelegate(header.getCompression()).getRawImageType(0);
|
||||
}
|
||||
default:
|
||||
throw new IIOException("Unsupported bit count: " + header.getBitCount());
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new IIOException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-7
@@ -29,9 +29,10 @@
|
||||
*/
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Describes a bitmap structure.
|
||||
@@ -47,14 +48,11 @@ abstract class BitmapDescriptor {
|
||||
protected BitmapMask mask;
|
||||
|
||||
public BitmapDescriptor(final DirectoryEntry pEntry, final DIBHeader pHeader) {
|
||||
Validate.notNull(pEntry, "entry");
|
||||
Validate.notNull(pHeader, "header");
|
||||
|
||||
entry = pEntry;
|
||||
header = pHeader;
|
||||
entry = notNull(pEntry, "entry");;
|
||||
header = notNull(pHeader, "header");
|
||||
}
|
||||
|
||||
abstract public BufferedImage getImage();
|
||||
abstract public BufferedImage getImage() throws IOException;
|
||||
|
||||
public final int getWidth() {
|
||||
return entry.getWidth();
|
||||
|
||||
+1
@@ -163,6 +163,7 @@ class BitmapIndexed extends BitmapDescriptor {
|
||||
return transparent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage getImage() {
|
||||
if (image == null) {
|
||||
image = createImageIndexed();
|
||||
|
||||
@@ -46,6 +46,7 @@ class BitmapRGB extends BitmapDescriptor {
|
||||
super(pEntry, pHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage getImage() {
|
||||
// Test is mask != null rather than hasMask(), as 32 bit (w/alpha)
|
||||
// might still have bitmask, but we don't read or use it.
|
||||
|
||||
+8
-4
@@ -31,6 +31,9 @@
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
/**
|
||||
* Represents bitmap structures we can't read.
|
||||
@@ -42,13 +45,14 @@ import java.awt.image.BufferedImage;
|
||||
class BitmapUnsupported extends BitmapDescriptor {
|
||||
private String message;
|
||||
|
||||
public BitmapUnsupported(final DirectoryEntry pEntry, final String pMessage) {
|
||||
super(pEntry, null);
|
||||
public BitmapUnsupported(final DirectoryEntry pEntry, DIBHeader header, final String pMessage) {
|
||||
super(pEntry, header);
|
||||
|
||||
message = pMessage;
|
||||
}
|
||||
|
||||
public BufferedImage getImage() {
|
||||
throw new IllegalStateException(message);
|
||||
@Override
|
||||
public BufferedImage getImage() throws IOException {
|
||||
throw new IIOException(message);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -30,11 +30,12 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
/**
|
||||
* Represents the DIB (Device Independent Bitmap) Information header structure.
|
||||
*
|
||||
@@ -213,7 +214,7 @@ abstract class DIBHeader {
|
||||
|
||||
// NOTE: Unlike all other headers, width and height are unsigned SHORT values (16 bit)!
|
||||
width = pStream.readUnsignedShort();
|
||||
height = pStream.readUnsignedShort();
|
||||
height = pStream.readShort();
|
||||
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
@@ -240,6 +241,7 @@ abstract class DIBHeader {
|
||||
* @see <a href="http://www.fileformat.info/format/os2bmp/egff.htm">OS/2 Bitmap File Format Summary</a>
|
||||
*/
|
||||
static final class BitmapCoreHeaderV2 extends DIBHeader {
|
||||
@SuppressWarnings("unused")
|
||||
protected void read(final int pSize, final DataInput pStream) throws IOException {
|
||||
if (pSize != DIB.OS2_V2_HEADER_SIZE && pSize != DIB.OS2_V2_HEADER_16_SIZE) {
|
||||
throw new IIOException(String.format("Size: %s !=: %s", pSize, DIB.OS2_V2_HEADER_SIZE));
|
||||
|
||||
+24
-17
@@ -30,16 +30,6 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.image.ImageUtil;
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
||||
import com.twelvemonkeys.util.WeakWeakMap;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.event.WindowAdapter;
|
||||
@@ -48,8 +38,26 @@ import java.awt.image.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.swing.*;
|
||||
|
||||
import com.twelvemonkeys.image.ImageUtil;
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
||||
import com.twelvemonkeys.util.WeakWeakMap;
|
||||
|
||||
/**
|
||||
* ImageReader for Microsoft Windows ICO (icon) format.
|
||||
@@ -287,7 +295,7 @@ abstract class DIBImageReader extends ImageReaderBase {
|
||||
|
||||
// TODO: Support this, it's already in the BMP reader, spec allows RLE4 and RLE8
|
||||
if (header.getCompression() != DIB.COMPRESSION_RGB) {
|
||||
descriptor = new BitmapUnsupported(pEntry, String.format("Unsupported compression: %d", header.getCompression()));
|
||||
descriptor = new BitmapUnsupported(pEntry, header, String.format("Unsupported compression: %d", header.getCompression()));
|
||||
}
|
||||
else {
|
||||
int bitCount = header.getBitCount();
|
||||
@@ -315,7 +323,7 @@ abstract class DIBImageReader extends ImageReaderBase {
|
||||
break;
|
||||
|
||||
default:
|
||||
descriptor = new BitmapUnsupported(pEntry, String.format("Unsupported bit count %d", bitCount));
|
||||
descriptor = new BitmapUnsupported(pEntry, header, String.format("Unsupported bit count %d", bitCount));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +363,7 @@ abstract class DIBImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private void readBitmapIndexed1(final BitmapIndexed pBitmap, final boolean pAsMask) throws IOException {
|
||||
int width = adjustToPadding(pBitmap.getWidth() >> 3);
|
||||
int width = adjustToPadding((pBitmap.getWidth() + 7) >> 3);
|
||||
byte[] row = new byte[width];
|
||||
|
||||
for (int y = 0; y < pBitmap.getHeight(); y++) {
|
||||
@@ -389,7 +397,7 @@ abstract class DIBImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private void readBitmapIndexed4(final BitmapIndexed pBitmap) throws IOException {
|
||||
int width = adjustToPadding(pBitmap.getWidth() >> 1);
|
||||
int width = adjustToPadding((pBitmap.getWidth() + 1) >> 1);
|
||||
byte[] row = new byte[width];
|
||||
|
||||
for (int y = 0; y < pBitmap.getHeight(); y++) {
|
||||
@@ -457,13 +465,12 @@ abstract class DIBImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private void readBitmap16(final BitmapDescriptor pBitmap) throws IOException {
|
||||
// TODO: No idea if this actually works..
|
||||
short[] pixels = new short[pBitmap.getWidth() * pBitmap.getHeight()];
|
||||
|
||||
// TODO: Support TYPE_USHORT_565 and the RGB 444/ARGB 4444 layouts
|
||||
// Will create TYPE_USHORT_555
|
||||
DirectColorModel cm = new DirectColorModel(16, 0x7C00, 0x03E0, 0x001F);
|
||||
DataBuffer buffer = new DataBufferShort(pixels, pixels.length);
|
||||
DataBuffer buffer = new DataBufferUShort(pixels, pixels.length);
|
||||
WritableRaster raster = Raster.createPackedRaster(
|
||||
buffer, pBitmap.getWidth(), pBitmap.getHeight(), pBitmap.getWidth(), cm.getMasks(), null
|
||||
);
|
||||
|
||||
+4
-4
@@ -41,8 +41,8 @@ import java.util.Arrays;
|
||||
* @version $Id: RLE4Decoder.java#1 $
|
||||
*/
|
||||
final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
final static int BIT_MASKS[] = {0xf0, 0x0f};
|
||||
final static int BIT_SHIFTS[] = {4, 0};
|
||||
final static int[] BIT_MASKS = {0xf0, 0x0f};
|
||||
final static int[] BIT_SHIFTS = {4, 0};
|
||||
|
||||
public RLE4Decoder(final int width) {
|
||||
super(width, 4);
|
||||
@@ -94,7 +94,7 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
boolean paddingByte = (((byte2 + 1) / 2) % 2) != 0;
|
||||
|
||||
int packed = 0;
|
||||
for (int i = 0; i < byte2; i++) {
|
||||
for (int i = 0; i < byte2 && srcX / 2 < row.length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
packed = checkEOF(stream.read());
|
||||
}
|
||||
@@ -111,7 +111,7 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
||||
else {
|
||||
// Encoded mode
|
||||
// Replicate the two samples in byte2 as many times as byte1 says
|
||||
for (int i = 0; i < byte1; i++) {
|
||||
for (int i = 0; i < byte1 && srcX / 2 < row.length; i++) {
|
||||
row[srcX / 2] |= (byte) (((byte2 & BIT_MASKS[i % 2]) >> BIT_SHIFTS[i % 2]) << BIT_SHIFTS[srcX % 2]);
|
||||
srcX++;
|
||||
}
|
||||
|
||||
+2
-2
@@ -94,7 +94,7 @@ final class RLE8Decoder extends AbstractRLEDecoder {
|
||||
// an additional padding byte is in the stream and must be skipped
|
||||
boolean paddingByte = (byte2 % 2) != 0;
|
||||
|
||||
while (byte2-- > 0) {
|
||||
while (byte2-- > 0 && srcX < row.length) {
|
||||
row[srcX++] = (byte) checkEOF(stream.read());
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ final class RLE8Decoder extends AbstractRLEDecoder {
|
||||
// Encoded mode
|
||||
// Replicate byte2 as many times as byte1 says
|
||||
byte value = (byte) byte2;
|
||||
while (byte1-- > 0) {
|
||||
while (byte1-- > 0 && srcX < row.length) {
|
||||
row[srcX++] = value;
|
||||
}
|
||||
}
|
||||
|
||||
+45
-41
@@ -30,35 +30,43 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
import com.twelvemonkeys.xml.XMLSerializer;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeNoException;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.event.IIOReadProgressListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.event.IIOReadProgressListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeNoException;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
import com.twelvemonkeys.xml.XMLSerializer;
|
||||
|
||||
/**
|
||||
* BMPImageReaderTest
|
||||
@@ -68,6 +76,12 @@ import static org.mockito.Mockito.*;
|
||||
* @version $Id: BMPImageReaderTest.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
|
||||
*/
|
||||
public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader> {
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new BMPImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
// BMP Suite "Good"
|
||||
@@ -144,27 +158,17 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader>
|
||||
);
|
||||
}
|
||||
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new BMPImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BMPImageReader createReader() {
|
||||
return new BMPImageReader(createProvider());
|
||||
}
|
||||
|
||||
protected Class<BMPImageReader> getReaderClass() {
|
||||
return BMPImageReader.class;
|
||||
}
|
||||
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("bmp");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSuffixes() {
|
||||
return Arrays.asList("bmp", "rle");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getMIMETypes() {
|
||||
return Collections.singletonList("image/bmp");
|
||||
}
|
||||
@@ -178,7 +182,7 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader>
|
||||
|
||||
ImageTypeSpecifier rawType = reader.getRawImageType(0);
|
||||
|
||||
// As the JPEGImageReader we delegate to returns null for YCbCr, we'll have to do the same
|
||||
// As the JPEGImageReader we delegate to may return null for YCbCr, we'll have to do the same
|
||||
if (rawType == null && data.getInput().toString().contains("jpeg")) {
|
||||
continue;
|
||||
}
|
||||
@@ -273,7 +277,7 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader>
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIIOReadProgressListenerCallbacksJPEG() {
|
||||
public void testAddIIOReadProgressListenerCallbacksJPEG() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = new TestData(getClassLoaderResource("/bmpsuite/q/rgb24jpeg.bmp"), new Dimension(127, 64));
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -296,7 +300,7 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader>
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIIOReadProgressListenerCallbacksPNG() {
|
||||
public void testAddIIOReadProgressListenerCallbacksPNG() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = new TestData(getClassLoaderResource("/bmpsuite/q/rgb24png.bmp"), new Dimension(127, 64));
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -319,7 +323,7 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader>
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataEqualsJRE() throws IOException, URISyntaxException {
|
||||
public void testMetadataEqualsJRE() throws IOException {
|
||||
ImageReader jreReader;
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -356,7 +360,7 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader>
|
||||
}
|
||||
IIOMetadata jreMetadata = jreReader.getImageMetadata(0);
|
||||
|
||||
assertEquals(true, metadata.isStandardMetadataFormatSupported());
|
||||
assertTrue(metadata.isStandardMetadataFormatSupported());
|
||||
assertEquals(jreMetadata.getNativeMetadataFormatName(), metadata.getNativeMetadataFormatName());
|
||||
assertArrayEquals(jreMetadata.getExtraMetadataFormatNames(), metadata.getExtraMetadataFormatNames());
|
||||
|
||||
@@ -379,7 +383,7 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest<BMPImageReader>
|
||||
new XMLSerializer(expected, "UTF-8").serialize(expectedTree, false);
|
||||
new XMLSerializer(actual, "UTF-8").serialize(actualTree, false);
|
||||
|
||||
assertEquals(e.getMessage(), new String(expected.toByteArray(), "UTF-8"), new String(actual.toByteArray(), "UTF-8"));
|
||||
assertEquals(e.getMessage(), new String(expected.toByteArray(), StandardCharsets.UTF_8), new String(actual.toByteArray(), StandardCharsets.UTF_8));
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
+6
-9
@@ -2,10 +2,10 @@ package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
|
||||
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -15,18 +15,15 @@ import java.util.List;
|
||||
* @author last modified by : harald.kuhr$
|
||||
* @version : BMPImageWriterTest.java,v 1.0 25/06/2020 harald.kuhr Exp$
|
||||
*/
|
||||
public class BMPImageWriterTest extends ImageWriterAbstractTest {
|
||||
|
||||
private final BMPImageWriterSpi provider = new BMPImageWriterSpi();
|
||||
|
||||
public class BMPImageWriterTest extends ImageWriterAbstractTest<BMPImageWriter> {
|
||||
@Override
|
||||
protected ImageWriter createImageWriter() {
|
||||
return provider.createWriterInstance(null);
|
||||
protected ImageWriterSpi createProvider() {
|
||||
return new BMPImageWriterSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends RenderedImage> getTestData() {
|
||||
return Arrays.asList(
|
||||
return Collections.singletonList(
|
||||
new BufferedImage(10, 10, BufferedImage.TYPE_4BYTE_ABGR)
|
||||
);
|
||||
}
|
||||
|
||||
+10
-13
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -53,6 +54,12 @@ import static org.junit.Assert.*;
|
||||
* @version $Id: CURImageReaderTest.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
|
||||
*/
|
||||
public class CURImageReaderTest extends ImageReaderAbstractTest<CURImageReader> {
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new CURImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
new TestData(getClassLoaderResource("/cur/hand.cur"), new Dimension(32, 32)),
|
||||
@@ -60,27 +67,17 @@ public class CURImageReaderTest extends ImageReaderAbstractTest<CURImageReader>
|
||||
);
|
||||
}
|
||||
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new CURImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CURImageReader createReader() {
|
||||
return new CURImageReader();
|
||||
}
|
||||
|
||||
protected Class<CURImageReader> getReaderClass() {
|
||||
return CURImageReader.class;
|
||||
}
|
||||
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("cur");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSuffixes() {
|
||||
return Collections.singletonList("cur");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getMIMETypes() {
|
||||
return Arrays.asList("image/vnd.microsoft.cursor", "image/cursor", "image/x-cursor");
|
||||
}
|
||||
@@ -99,7 +96,7 @@ public class CURImageReaderTest extends ImageReaderAbstractTest<CURImageReader>
|
||||
assertNotNull("Hotspot for cursor not present", hotspot);
|
||||
|
||||
// Image weirdness
|
||||
assertTrue("Hotspot for cursor undefined (java.awt.Image.UndefinedProperty)", Image.UndefinedProperty != hotspot);
|
||||
assertNotSame("Hotspot for cursor undefined (java.awt.Image.UndefinedProperty)", Image.UndefinedProperty, hotspot);
|
||||
|
||||
assertTrue(String.format("Hotspot not a java.awt.Point: %s", hotspot.getClass()), hotspot instanceof Point);
|
||||
assertEquals(pExpected, hotspot);
|
||||
|
||||
+9
-12
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -49,6 +50,12 @@ import java.util.List;
|
||||
* @version $Id: ICOImageReaderTest.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
|
||||
*/
|
||||
public class ICOImageReaderTest extends ImageReaderAbstractTest<ICOImageReader> {
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new ICOImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
new TestData(
|
||||
@@ -75,27 +82,17 @@ public class ICOImageReaderTest extends ImageReaderAbstractTest<ICOImageReader>
|
||||
);
|
||||
}
|
||||
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new ICOImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ICOImageReader createReader() {
|
||||
return new ICOImageReader();
|
||||
}
|
||||
|
||||
protected Class<ICOImageReader> getReaderClass() {
|
||||
return ICOImageReader.class;
|
||||
}
|
||||
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("ico");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSuffixes() {
|
||||
return Collections.singletonList("ico");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getMIMETypes() {
|
||||
return Arrays.asList("image/vnd.microsoft.icon", "image/ico", "image/x-icon");
|
||||
}
|
||||
|
||||
+4
-6
@@ -2,7 +2,7 @@ package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
|
||||
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.util.Arrays;
|
||||
@@ -15,12 +15,10 @@ import java.util.List;
|
||||
* @author last modified by : harald.kuhr$
|
||||
* @version : ICOImageWriterTest.java,v 1.0 25/06/2020 harald.kuhr Exp$
|
||||
*/
|
||||
public class ICOImageWriterTest extends ImageWriterAbstractTest {
|
||||
private final ICOImageWriterSpi provider = new ICOImageWriterSpi();
|
||||
|
||||
public class ICOImageWriterTest extends ImageWriterAbstractTest<ICOImageWriter> {
|
||||
@Override
|
||||
protected ImageWriter createImageWriter() {
|
||||
return provider.createWriterInstance(null);
|
||||
protected ImageWriterSpi createProvider() {
|
||||
return new ICOImageWriterSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-clippath</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: Photoshop Path Support</name>
|
||||
@@ -21,6 +21,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: Core</name>
|
||||
|
||||
@@ -30,20 +30,16 @@
|
||||
|
||||
package com.twelvemonkeys.imageio;
|
||||
|
||||
import com.twelvemonkeys.image.BufferedImageIcon;
|
||||
import com.twelvemonkeys.image.ImageUtil;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.awt.event.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.io.File;
|
||||
@@ -52,6 +48,20 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.swing.*;
|
||||
|
||||
import com.twelvemonkeys.image.BufferedImageIcon;
|
||||
import com.twelvemonkeys.image.ImageUtil;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
|
||||
/**
|
||||
* Abstract base class for image readers.
|
||||
*
|
||||
@@ -314,12 +324,12 @@ public abstract class ImageReaderBase extends ImageReader {
|
||||
|
||||
long dimension = (long) destWidth * destHeight;
|
||||
if (dimension > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException(String.format("destination width * height > Integer.MAX_VALUE: %d", dimension));
|
||||
throw new IIOException(String.format("destination width * height > Integer.MAX_VALUE: %d", dimension));
|
||||
}
|
||||
|
||||
long size = dimension * imageType.getSampleModel().getNumDataElements();
|
||||
if (size > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException(String.format("destination width * height * samplesPerPixel > Integer.MAX_VALUE: %d", size));
|
||||
throw new IIOException(String.format("destination width * height * samplesPerPixel > Integer.MAX_VALUE: %d", size));
|
||||
}
|
||||
|
||||
// Create a new image based on the type specifier
|
||||
|
||||
+20
-17
@@ -57,8 +57,10 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
|
||||
|
||||
private ImageInputStream stream;
|
||||
|
||||
private ByteBuffer buffer;
|
||||
private ByteBuffer integralCache = ByteBuffer.allocate(8);
|
||||
private ByteBuffer buffer;
|
||||
|
||||
private final ByteBuffer integralCache = ByteBuffer.allocate(8);
|
||||
private final byte[] integralCacheArray = integralCache.array();
|
||||
|
||||
public BufferedImageInputStream(final ImageInputStream pStream) throws IOException {
|
||||
this(pStream, DEFAULT_BUFFER_SIZE);
|
||||
@@ -97,10 +99,10 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
|
||||
|
||||
if (!buffer.hasRemaining()) {
|
||||
fillBuffer();
|
||||
}
|
||||
|
||||
if (!buffer.hasRemaining()) {
|
||||
return -1;
|
||||
if (!buffer.hasRemaining()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bitOffset = 0;
|
||||
@@ -172,21 +174,21 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
|
||||
|
||||
@Override
|
||||
public short readShort() throws IOException {
|
||||
readFully(integralCache.array(), 0, 2);
|
||||
readFully(integralCacheArray, 0, 2);
|
||||
|
||||
return integralCache.getShort(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt() throws IOException {
|
||||
readFully(integralCache.array(), 0, 4);
|
||||
readFully(integralCacheArray, 0, 4);
|
||||
|
||||
return integralCache.getInt(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong() throws IOException {
|
||||
readFully(integralCache.array(), 0, 8);
|
||||
readFully(integralCacheArray, 0, 8);
|
||||
|
||||
return integralCache.getLong(0);
|
||||
}
|
||||
@@ -253,6 +255,7 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
|
||||
}
|
||||
|
||||
int val = buffer.get() & 0xff;
|
||||
streamPos++;
|
||||
|
||||
accum <<= 8;
|
||||
accum |= val;
|
||||
@@ -262,9 +265,7 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
|
||||
// Move byte position back if in the middle of a byte
|
||||
if (newBitOffset != 0) {
|
||||
buffer.position(buffer.position() - 1);
|
||||
}
|
||||
else {
|
||||
streamPos++;
|
||||
streamPos--;
|
||||
}
|
||||
|
||||
this.bitOffset = newBitOffset;
|
||||
@@ -279,26 +280,26 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long pPosition) throws IOException {
|
||||
public void seek(long position) throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
|
||||
if (streamPos == pPosition) {
|
||||
if (streamPos == position) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Optimized to not invalidate buffer if new position is within current buffer
|
||||
long newBufferPos = buffer.position() + pPosition - streamPos;
|
||||
long newBufferPos = buffer.position() + position - streamPos;
|
||||
if (newBufferPos >= 0 && newBufferPos <= buffer.limit()) {
|
||||
buffer.position((int) newBufferPos);
|
||||
}
|
||||
else {
|
||||
// Will invalidate buffer
|
||||
buffer.limit(0);
|
||||
stream.seek(pPosition);
|
||||
stream.seek(position);
|
||||
}
|
||||
|
||||
streamPos = pPosition;
|
||||
streamPos = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -330,7 +331,9 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (stream != null) {
|
||||
//stream.close();
|
||||
// TODO: FixMe: Need to close underlying stream here!
|
||||
// For call sites that relies on not closing, we should instead not close the buffered stream.
|
||||
// stream.close();
|
||||
stream = null;
|
||||
buffer = null;
|
||||
}
|
||||
|
||||
+8
-3
@@ -30,10 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ProviderInfo;
|
||||
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@@ -47,10 +48,14 @@ import java.util.Locale;
|
||||
public class ByteArrayImageInputStreamSpi extends ImageInputStreamSpi {
|
||||
|
||||
public ByteArrayImageInputStreamSpi() {
|
||||
super("TwelveMonkeys", "1.0 BETA", byte[].class);
|
||||
this(new StreamProviderInfo());
|
||||
}
|
||||
|
||||
public ImageInputStream createInputStreamInstance(Object pInput, boolean pUseCache, File pCacheDir) throws IOException {
|
||||
private ByteArrayImageInputStreamSpi(ProviderInfo providerInfo) {
|
||||
super(providerInfo.getVendorName(), providerInfo.getVersion(), byte[].class);
|
||||
}
|
||||
|
||||
public ImageInputStream createInputStreamInstance(Object pInput, boolean pUseCache, File pCacheDir) {
|
||||
if (pInput instanceof byte[]) {
|
||||
return new ByteArrayImageInputStream((byte[]) pInput);
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ProviderInfo;
|
||||
|
||||
final class StreamProviderInfo extends ProviderInfo {
|
||||
StreamProviderInfo() {
|
||||
super(StreamProviderInfo.class.getPackage());
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -30,6 +30,8 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ProviderInfo;
|
||||
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
import javax.imageio.stream.FileCacheImageInputStream;
|
||||
import javax.imageio.stream.FileImageInputStream;
|
||||
@@ -53,7 +55,11 @@ import java.util.Locale;
|
||||
// TODO: URI instead of URL?
|
||||
public class URLImageInputStreamSpi extends ImageInputStreamSpi {
|
||||
public URLImageInputStreamSpi() {
|
||||
super("TwelveMonkeys", "1.0 BETA", URL.class);
|
||||
this(new StreamProviderInfo());
|
||||
}
|
||||
|
||||
private URLImageInputStreamSpi(ProviderInfo providerInfo) {
|
||||
super(providerInfo.getVendorName(), providerInfo.getVersion(), URL.class);
|
||||
}
|
||||
|
||||
// TODO: Create a URI or URLImageInputStream class, with a getUR[I|L] method, to allow for multiple file formats
|
||||
@@ -108,6 +114,11 @@ public class URLImageInputStreamSpi extends ImageInputStreamSpi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUseCacheFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getDescription(final Locale pLocale) {
|
||||
return "Service provider that instantiates an ImageInputStream from a URL";
|
||||
}
|
||||
|
||||
@@ -291,4 +291,21 @@ public final class IIOUtil {
|
||||
System.arraycopy(srcRow, srcPos + x, destRow, destPos + x / samplePeriod, pixelStride);
|
||||
}
|
||||
}
|
||||
|
||||
public static void subsampleRow(float[] srcRow, int srcPos, int srcWidth,
|
||||
float[] destRow, int destPos,
|
||||
int samplesPerPixel, int bitsPerSample, int samplePeriod) {
|
||||
Validate.isTrue(samplePeriod > 1, "samplePeriod must be > 1"); // Period == 1 could be a no-op...
|
||||
Validate.isTrue(bitsPerSample > 0 && bitsPerSample <= 32 && (bitsPerSample == 1 || bitsPerSample % 2 == 0),
|
||||
"bitsPerSample must be > 0 and <= 32 and a power of 2");
|
||||
Validate.isTrue(samplesPerPixel > 0, "samplesPerPixel must be > 0");
|
||||
Validate.isTrue(samplesPerPixel * bitsPerSample <= 32 || samplesPerPixel * bitsPerSample % 32 == 0,
|
||||
"samplesPerPixel * bitsPerSample must be < 32 or a multiple of 32 ");
|
||||
|
||||
int pixelStride = bitsPerSample * samplesPerPixel / 32;
|
||||
for (int x = 0; x < srcWidth * pixelStride; x += samplePeriod * pixelStride) {
|
||||
// System.arraycopy should be intrinsic, but consider using direct array access for pixelStride == 1
|
||||
System.arraycopy(srcRow, srcPos + x, destRow, destPos + x / samplePeriod, pixelStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-9
@@ -30,11 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.imageio;
|
||||
|
||||
import org.junit.Test;
|
||||
import static java.util.Collections.singleton;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -44,8 +44,11 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.singleton;
|
||||
import static org.junit.Assert.*;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* ImageReaderBaseTest
|
||||
@@ -212,19 +215,19 @@ public class ImageReaderBaseTest {
|
||||
assertEquals(TYPES.get(0).getBufferedImageType(), destination.getType());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = IIOException.class)
|
||||
public void testGetDestinationParamDestinationExceedsIntegerMax() throws IIOException {
|
||||
ImageReadParam param = new ImageReadParam();
|
||||
param.setSourceRegion(new Rectangle(3 * Short.MAX_VALUE, 2 * Short.MAX_VALUE)); // 6 442 057 734 pixels
|
||||
ImageReaderBase.getDestination(param, TYPES.iterator(), 6 * Short.MAX_VALUE, 4 * Short.MAX_VALUE); // 25 768 230 936 pixels
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = IIOException.class)
|
||||
public void testGetDestinationDimensionExceedsIntegerMax() throws IIOException {
|
||||
ImageReaderBase.getDestination(null, TYPES.iterator(), 3 * Short.MAX_VALUE, 2 * Short.MAX_VALUE); // 6 442 057 734 pixels
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = IIOException.class)
|
||||
public void testGetDestinationStorageExceedsIntegerMax() throws IIOException {
|
||||
Set<ImageTypeSpecifier> byteTypes = singleton(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR));
|
||||
ImageReaderBase.getDestination(null, byteTypes.iterator(), Short.MAX_VALUE, Short.MAX_VALUE); // 1 073 676 289 pixels
|
||||
|
||||
+4
-2
@@ -35,6 +35,8 @@ import org.junit.Test;
|
||||
|
||||
import java.awt.image.*;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class DiscreteAlphaIndexColorModelTest {
|
||||
@@ -162,7 +164,7 @@ public class DiscreteAlphaIndexColorModelTest {
|
||||
assertEquals(2, sampleModel.getHeight());
|
||||
|
||||
assertTrue(colorModel.isCompatibleSampleModel(sampleModel));
|
||||
assertThat(sampleModel, CoreMatchers.is(PixelInterleavedSampleModel.class));
|
||||
assertThat(sampleModel, instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertThat(sampleModel.getDataType(), CoreMatchers.equalTo(DataBuffer.TYPE_BYTE));
|
||||
}
|
||||
|
||||
@@ -180,7 +182,7 @@ public class DiscreteAlphaIndexColorModelTest {
|
||||
assertEquals(2, sampleModel.getHeight());
|
||||
|
||||
assertTrue(colorModel.isCompatibleSampleModel(sampleModel));
|
||||
assertThat(sampleModel, CoreMatchers.is(PixelInterleavedSampleModel.class));
|
||||
assertThat(sampleModel, instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertThat(sampleModel.getDataType(), CoreMatchers.equalTo(DataBuffer.TYPE_USHORT));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ import static org.junit.Assert.*;
|
||||
*/
|
||||
public class ProviderInfoTest {
|
||||
@Test
|
||||
public void testCreateNorma() {
|
||||
public void testCreateNormal() {
|
||||
new ProviderInfo(Package.getPackage("java.util"));
|
||||
}
|
||||
|
||||
|
||||
+15
-14
@@ -31,8 +31,8 @@
|
||||
package com.twelvemonkeys.imageio.spi;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.matchers.TypeSafeMatcher;
|
||||
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageWriter;
|
||||
@@ -42,6 +42,7 @@ import javax.imageio.spi.ImageWriterSpi;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
@@ -62,52 +63,52 @@ public abstract class ReaderWriterProviderInfoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readerClassName() throws Exception {
|
||||
public void readerClassName() {
|
||||
assertClassExists(providerInfo.readerClassName(), ImageReader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readerSpiClassNames() throws Exception {
|
||||
public void readerSpiClassNames() {
|
||||
assertClassesExist(providerInfo.readerSpiClassNames(), ImageReaderSpi.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inputTypes() throws Exception {
|
||||
public void inputTypes() {
|
||||
assertNotNull(providerInfo.inputTypes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writerClassName() throws Exception {
|
||||
public void writerClassName() {
|
||||
assertClassExists(providerInfo.writerClassName(), ImageWriter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writerSpiClassNames() throws Exception {
|
||||
public void writerSpiClassNames() {
|
||||
assertClassesExist(providerInfo.writerSpiClassNames(), ImageWriterSpi.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputTypes() throws Exception {
|
||||
public void outputTypes() {
|
||||
assertNotNull(providerInfo.outputTypes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeStreamMetadataFormatClassName() throws Exception {
|
||||
public void nativeStreamMetadataFormatClassName() {
|
||||
assertClassExists(providerInfo.nativeStreamMetadataFormatClassName(), IIOMetadataFormat.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraStreamMetadataFormatClassNames() throws Exception {
|
||||
public void extraStreamMetadataFormatClassNames() {
|
||||
assertClassesExist(providerInfo.extraStreamMetadataFormatClassNames(), IIOMetadataFormat.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeImageMetadataFormatClassName() throws Exception {
|
||||
public void nativeImageMetadataFormatClassName() {
|
||||
assertClassExists(providerInfo.nativeImageMetadataFormatClassName(), IIOMetadataFormat.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraImageMetadataFormatClassNames() throws Exception {
|
||||
public void extraImageMetadataFormatClassNames() {
|
||||
assertClassesExist(providerInfo.extraImageMetadataFormatClassNames(), IIOMetadataFormat.class);
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ public abstract class ReaderWriterProviderInfoTest {
|
||||
public void formatNames() {
|
||||
String[] names = providerInfo.formatNames();
|
||||
assertNotNull(names);
|
||||
assertFalse(names.length == 0);
|
||||
assertNotEquals(0, names.length);
|
||||
|
||||
List<String> list = asList(names);
|
||||
|
||||
@@ -132,7 +133,7 @@ public abstract class ReaderWriterProviderInfoTest {
|
||||
public void suffixes() {
|
||||
String[] suffixes = providerInfo.suffixes();
|
||||
assertNotNull(suffixes);
|
||||
assertFalse(suffixes.length == 0);
|
||||
assertNotEquals(0, suffixes.length);
|
||||
|
||||
for (String suffix : suffixes) {
|
||||
assertNotNull(suffix);
|
||||
@@ -144,7 +145,7 @@ public abstract class ReaderWriterProviderInfoTest {
|
||||
public void mimeTypes() {
|
||||
String[] mimeTypes = providerInfo.mimeTypes();
|
||||
assertNotNull(mimeTypes);
|
||||
assertFalse(mimeTypes.length == 0);
|
||||
assertNotEquals(0, mimeTypes.length);
|
||||
|
||||
for (String mimeType : mimeTypes) {
|
||||
assertNotNull(mimeType);
|
||||
|
||||
+254
@@ -32,16 +32,19 @@ package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import com.twelvemonkeys.io.ole2.CompoundDocument;
|
||||
import com.twelvemonkeys.io.ole2.Entry;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Random;
|
||||
|
||||
import static java.util.Arrays.fill;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* BufferedImageInputStreamTest
|
||||
@@ -72,6 +75,257 @@ public class BufferedImageInputStreamTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBit() throws IOException {
|
||||
byte[] bytes = new byte[] {(byte) 0xF0, (byte) 0x0F};
|
||||
|
||||
// Create wrapper stream
|
||||
BufferedImageInputStream stream = new BufferedImageInputStream(new ByteArrayImageInputStream(bytes));
|
||||
|
||||
// Read all bits
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(2, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(3, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(4, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(5, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(6, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(7, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBit()); // last bit
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
// Full reset, read same sequence again
|
||||
stream.seek(0);
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(0, stream.readBit());
|
||||
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
// Full reset, read partial
|
||||
stream.seek(0);
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.readBit());
|
||||
|
||||
// Byte reset, read same sequence again
|
||||
stream.setBitOffset(0);
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(0, stream.readBit());
|
||||
|
||||
// Byte reset, read partial sequence again
|
||||
stream.setBitOffset(3);
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
// Byte reset, read partial sequence again
|
||||
stream.setBitOffset(6);
|
||||
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
// Read all bits, second byte
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(1, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(2, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(3, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBit());
|
||||
assertEquals(4, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(5, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(6, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit());
|
||||
assertEquals(7, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(1, stream.readBit()); // last bit
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(2, stream.getStreamPosition());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBits() throws IOException {
|
||||
byte[] bytes = new byte[] {(byte) 0xF0, (byte) 0xCC, (byte) 0xAA};
|
||||
|
||||
// Create wrapper stream
|
||||
BufferedImageInputStream stream = new BufferedImageInputStream(new ByteArrayImageInputStream(bytes));
|
||||
|
||||
// Read all bits, first byte
|
||||
assertEquals(3, stream.readBits(2));
|
||||
assertEquals(2, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(3, stream.readBits(2));
|
||||
assertEquals(4, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBits(2));
|
||||
assertEquals(6, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBits(2));
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
// Read all bits, second byte
|
||||
assertEquals(3, stream.readBits(2));
|
||||
assertEquals(2, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBits(2));
|
||||
assertEquals(4, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(3, stream.readBits(2));
|
||||
assertEquals(6, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0, stream.readBits(2));
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(2, stream.getStreamPosition());
|
||||
|
||||
// Read all bits, third byte
|
||||
assertEquals(2, stream.readBits(2));
|
||||
assertEquals(2, stream.getBitOffset());
|
||||
assertEquals(2, stream.getStreamPosition());
|
||||
|
||||
assertEquals(2, stream.readBits(2));
|
||||
assertEquals(4, stream.getBitOffset());
|
||||
assertEquals(2, stream.getStreamPosition());
|
||||
|
||||
assertEquals(2, stream.readBits(2));
|
||||
assertEquals(6, stream.getBitOffset());
|
||||
assertEquals(2, stream.getStreamPosition());
|
||||
|
||||
assertEquals(2, stream.readBits(2));
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(3, stream.getStreamPosition());
|
||||
|
||||
// Full reset, read same sequence again
|
||||
stream.seek(0);
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
// Read all bits, increasing size
|
||||
assertEquals(7, stream.readBits(3)); // 111
|
||||
assertEquals(3, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(8, stream.readBits(4)); // 1000
|
||||
assertEquals(7, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(12, stream.readBits(5)); // 01100
|
||||
assertEquals(4, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(50, stream.readBits(6)); // 110010
|
||||
assertEquals(2, stream.getBitOffset());
|
||||
assertEquals(2, stream.getStreamPosition());
|
||||
|
||||
assertEquals(42, stream.readBits(6)); // 101010
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(3, stream.getStreamPosition());
|
||||
|
||||
// Full reset, read same sequence again
|
||||
stream.seek(0);
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
// Read all bits multi-byte
|
||||
assertEquals(0xF0C, stream.readBits(12)); // 111100001100
|
||||
assertEquals(4, stream.getBitOffset());
|
||||
assertEquals(1, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0xCAA, stream.readBits(12)); // 110010101010
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(3, stream.getStreamPosition());
|
||||
|
||||
// Full reset, read same sequence again, all bits in one go
|
||||
stream.seek(0);
|
||||
assertEquals(0, stream.getBitOffset());
|
||||
assertEquals(0, stream.getStreamPosition());
|
||||
|
||||
assertEquals(0xF0CCAA, stream.readBits(24));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBitsRandom() throws IOException {
|
||||
long value = random.nextLong();
|
||||
byte[] bytes = new byte[8];
|
||||
ByteBuffer.wrap(bytes).putLong(value);
|
||||
|
||||
// Create wrapper stream
|
||||
BufferedImageInputStream stream = new BufferedImageInputStream(new ByteArrayImageInputStream(bytes));
|
||||
|
||||
for (int i = 1; i < 64; i++) {
|
||||
stream.seek(0);
|
||||
assertEquals(i + " bits differ", value >>> (64L - i), stream.readBits(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose() throws IOException {
|
||||
// Create wrapper stream
|
||||
ImageInputStream mock = mock(ImageInputStream.class);
|
||||
BufferedImageInputStream stream = new BufferedImageInputStream(mock);
|
||||
|
||||
stream.close();
|
||||
verify(mock, never()).close();
|
||||
}
|
||||
|
||||
// TODO: Write other tests
|
||||
|
||||
// TODO: Create test that exposes read += -1 (eof) bug
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
|
||||
public class ByteArrayImageInputStreamSpiTest extends ImageInputStreamSpiTest<byte[]> {
|
||||
|
||||
@Override
|
||||
protected ImageInputStreamSpi createProvider() {
|
||||
return new ByteArrayImageInputStreamSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] createInput() {
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
abstract class ImageInputStreamSpiTest<T> {
|
||||
private final ImageInputStreamSpi provider = createProvider();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Class<T> inputClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
|
||||
protected abstract ImageInputStreamSpi createProvider();
|
||||
|
||||
protected abstract T createInput();
|
||||
|
||||
@Test
|
||||
public void testInputClass() {
|
||||
assertEquals(inputClass, provider.getInputClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVendorName() {
|
||||
assertNotNull(provider.getVendorName());
|
||||
assertEquals("TwelveMonkeys", provider.getVendorName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersion() {
|
||||
assertNotNull(provider.getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescription() {
|
||||
assertNotNull(provider.getDescription(null));
|
||||
assertNotNull(provider.getDescription(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createNull() throws IOException {
|
||||
provider.createInputStreamInstance(null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createNullCached() throws IOException {
|
||||
provider.createInputStreamInstance(null, true, ImageIO.getCacheDirectory());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createCachedNullCache() throws IOException {
|
||||
try {
|
||||
provider.createInputStreamInstance(createInput(), true, null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
// All good
|
||||
assertFalse(provider.needsCacheFile());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create() throws IOException {
|
||||
assertNotNull(provider.createInputStreamInstance(createInput()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createCached() throws IOException {
|
||||
if (provider.canUseCacheFile()) {
|
||||
assertNotNull(provider.createInputStreamInstance(createInput(), true, ImageIO.getCacheDirectory()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createNonCached() throws IOException {
|
||||
if (!provider.needsCacheFile()) {
|
||||
assertNotNull(provider.createInputStreamInstance(createInput(), false, ImageIO.getCacheDirectory()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ProviderInfo;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class StreamProviderInfoTest {
|
||||
private final ProviderInfo providerInfo = new StreamProviderInfo();
|
||||
|
||||
@Test
|
||||
public void testVendorName() {
|
||||
assertNotNull(providerInfo.getVendorName());
|
||||
assertEquals("TwelveMonkeys", providerInfo.getVendorName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersion() {
|
||||
assertNotNull(providerInfo.getVersion());
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.twelvemonkeys.imageio.stream;
|
||||
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
import java.net.URL;
|
||||
|
||||
public class URLImageInputStreamSpiTest extends ImageInputStreamSpiTest<URL> {
|
||||
@Override
|
||||
protected ImageInputStreamSpi createProvider() {
|
||||
return new URLImageInputStreamSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URL createInput() {
|
||||
return getClass().getResource("/empty-stream.txt");
|
||||
}
|
||||
}
|
||||
+115
-105
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.util;
|
||||
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
@@ -49,6 +50,7 @@ import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -69,27 +71,26 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
// TODO: Should we really test if the provider is installed?
|
||||
// - Pro: Tests the META-INF/services config
|
||||
// - Con: Not all providers should be installed at runtime...
|
||||
// TODO: Create own subclass for testing the Spis?
|
||||
|
||||
static {
|
||||
IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi());
|
||||
ImageIO.setUseCache(false);
|
||||
}
|
||||
|
||||
protected abstract List<TestData> getTestData();
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Class<T> readerClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
|
||||
protected final ImageReaderSpi provider = createProvider();
|
||||
|
||||
protected abstract ImageReaderSpi createProvider();
|
||||
|
||||
protected abstract Class<T> getReaderClass();
|
||||
|
||||
protected T createReader() {
|
||||
try {
|
||||
return getReaderClass().newInstance();
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
protected final T createReader() throws IOException {
|
||||
return readerClass.cast(provider.createReaderInstance(null));
|
||||
}
|
||||
|
||||
protected abstract List<TestData> getTestData();
|
||||
|
||||
protected abstract List<String> getFormatNames();
|
||||
|
||||
protected abstract List<String> getSuffixes();
|
||||
@@ -101,9 +102,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
protected static void failBecause(String message, Throwable exception) {
|
||||
AssertionError error = new AssertionError(message);
|
||||
error.initCause(exception);
|
||||
throw error;
|
||||
throw new AssertionError(message, exception);
|
||||
}
|
||||
|
||||
protected void assertProviderInstalledForName(final String pFormat, final Class<? extends ImageReader> pReaderClass) {
|
||||
@@ -123,17 +122,20 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
boolean found = false;
|
||||
while (pReaders.hasNext()) {
|
||||
ImageReader reader = pReaders.next();
|
||||
if (reader.getClass() == pReaderClass) {
|
||||
if (reader.getClass() == pReaderClass && isOurProvider(reader.getOriginatingProvider())) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(String.format("%s not installed for %s", pReaderClass.getSimpleName(), pFormat), found);
|
||||
assertTrue(String.format("%s not provided by %s for '%s'", pReaderClass.getSimpleName(), provider.getClass().getSimpleName(), pFormat), found);
|
||||
}
|
||||
|
||||
private boolean isOurProvider(final ImageReaderSpi spi) {
|
||||
return provider.getClass().isInstance(spi);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderInstalledForNames() {
|
||||
Class<? extends ImageReader> readerClass = getReaderClass();
|
||||
for (String name : getFormatNames()) {
|
||||
assertProviderInstalledForName(name, readerClass);
|
||||
}
|
||||
@@ -141,7 +143,6 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
|
||||
@Test
|
||||
public void testProviderInstalledForSuffixes() {
|
||||
Class<? extends ImageReader> readerClass = getReaderClass();
|
||||
for (String suffix : getSuffixes()) {
|
||||
assertProviderInstalledForSuffix(suffix, readerClass);
|
||||
}
|
||||
@@ -149,7 +150,6 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
|
||||
@Test
|
||||
public void testProviderInstalledForMIMETypes() {
|
||||
Class<? extends ImageReader> readerClass = getReaderClass();
|
||||
for (String type : getMIMETypes()) {
|
||||
assertProviderInstalledForMIMEType(type, readerClass);
|
||||
}
|
||||
@@ -159,7 +159,6 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
public void testProviderCanRead() throws IOException {
|
||||
List<TestData> testData = getTestData();
|
||||
|
||||
ImageReaderSpi provider = createProvider();
|
||||
for (TestData data : testData) {
|
||||
ImageInputStream stream = data.getInputStream();
|
||||
assertNotNull(stream);
|
||||
@@ -172,7 +171,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
boolean canRead = false;
|
||||
|
||||
try {
|
||||
canRead = createProvider().canDecodeInput(null);
|
||||
canRead = provider.canDecodeInput(null);
|
||||
}
|
||||
catch (IllegalArgumentException ignore) {
|
||||
}
|
||||
@@ -187,7 +186,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetInput() {
|
||||
public void testSetInput() throws IOException {
|
||||
// Should just pass with no exceptions
|
||||
ImageReader reader = createReader();
|
||||
assertNotNull(reader);
|
||||
@@ -200,7 +199,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetInputNull() {
|
||||
public void testSetInputNull() throws IOException {
|
||||
// Should just pass with no exceptions
|
||||
ImageReader reader = createReader();
|
||||
assertNotNull(reader);
|
||||
@@ -209,7 +208,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() {
|
||||
public void testRead() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
|
||||
for (TestData data : getTestData()) {
|
||||
@@ -243,7 +242,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndexNegative() {
|
||||
public void testReadIndexNegative() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -264,7 +263,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndexOutOfBounds() {
|
||||
public void testReadIndexOutOfBounds() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -285,7 +284,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadNoInput() {
|
||||
public void testReadNoInput() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
// Do not set input
|
||||
|
||||
@@ -325,7 +324,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndexNegativeWithParam() {
|
||||
public void testReadIndexNegativeWithParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -347,7 +346,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadIndexOutOfBoundsWithParam() {
|
||||
public void testReadIndexOutOfBoundsWithParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -369,7 +368,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadNoInputWithParam() {
|
||||
public void testReadNoInputWithParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
// Do not set input
|
||||
|
||||
@@ -390,7 +389,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithNewParam() {
|
||||
public void testReadWithNewParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -411,7 +410,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithDefaultParam() {
|
||||
public void testReadWithDefaultParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -432,7 +431,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithNullParam() {
|
||||
public void testReadWithNullParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -453,7 +452,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithSizeParam() {
|
||||
public void testReadWithSizeParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -479,7 +478,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithSubsampleParamDimensions() {
|
||||
public void testReadWithSubsampleParamDimensions() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -530,6 +529,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
// TODO: Subsample all test data
|
||||
// TODO: Subsample with varying ratios and offsets
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
protected final void assertSubsampledImageDataEquals(String message, BufferedImage expected, BufferedImage actual, ImageReadParam param) throws IOException {
|
||||
assertNotNull("Expected image was null", expected);
|
||||
assertNotNull("Actual image was null!", actual);
|
||||
@@ -595,7 +595,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithSourceRegionParam() {
|
||||
public void testReadWithSourceRegionParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -626,40 +626,53 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
|
||||
protected void assertReadWithSourceRegionParamEqualImage(final Rectangle r, final TestData data, final int imageIndex) throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
reader.setInput(data.getInputStream());
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
try (ImageInputStream inputStream = data.getInputStream()) {
|
||||
reader.setInput(inputStream);
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
|
||||
// Read full image and get sub image for comparison
|
||||
final BufferedImage roi = reader.read(imageIndex, param).getSubimage(r.x, r.y, r.width, r.height);
|
||||
// Read full image and get sub image for comparison
|
||||
BufferedImage original = reader.read(imageIndex, param);
|
||||
final BufferedImage roi = original.getSubimage(r.x, r.y, r.width, r.height);
|
||||
|
||||
param.setSourceRegion(r);
|
||||
param.setSourceRegion(r);
|
||||
|
||||
final BufferedImage image = reader.read(imageIndex, param);
|
||||
final BufferedImage image = reader.read(imageIndex, param);
|
||||
|
||||
// try {
|
||||
// SwingUtilities.invokeAndWait(new Runnable() {
|
||||
// public void run() {
|
||||
// JPanel panel = new JPanel(new FlowLayout());
|
||||
// panel.add(new JLabel(new BufferedImageIcon(roi, r.width * 10, r.height * 10, true)));
|
||||
// panel.add(new JLabel(new BufferedImageIcon(image, r.width * 10, r.height * 10, true)));
|
||||
// JOptionPane.showConfirmDialog(null, panel);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// catch (Exception e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
assertNotNull("Image was null!", image);
|
||||
assertEquals("Read image has wrong width: " + image.getWidth(), r.width, image.getWidth());
|
||||
assertEquals("Read image has wrong height: " + image.getHeight(), r.height, image.getHeight());
|
||||
|
||||
assertNotNull("Image was null!", image);
|
||||
assertEquals("Read image has wrong width: " + image.getWidth(), r.width, image.getWidth());
|
||||
assertEquals("Read image has wrong height: " + image.getHeight(), r.height, image.getHeight());
|
||||
assertImageDataEquals("Images differ", roi, image);
|
||||
try {
|
||||
assertImageDataEquals("Images differ", roi, image);
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
File tempExpected = File.createTempFile("junit-expected-", ".png");
|
||||
System.err.println("tempExpected.getAbsolutePath(): " + tempExpected.getAbsolutePath());
|
||||
|
||||
reader.dispose();
|
||||
Graphics2D graphics = original.createGraphics();
|
||||
try {
|
||||
graphics.setColor(Color.RED);
|
||||
graphics.draw(r);
|
||||
}
|
||||
finally {
|
||||
graphics.dispose();
|
||||
}
|
||||
|
||||
ImageIO.write(original, "PNG", tempExpected);
|
||||
File tempActual = File.createTempFile("junit-actual-", ".png");
|
||||
System.err.println("tempActual.getAbsolutePath(): " + tempActual.getAbsolutePath());
|
||||
ImageIO.write(image, "PNG", tempActual);
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
reader.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithSizeAndSourceRegionParam() {
|
||||
public void testReadWithSizeAndSourceRegionParam() throws IOException {
|
||||
// TODO: Is this test correct???
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
@@ -690,7 +703,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithSubsampleAndSourceRegionParam() {
|
||||
public void testReadWithSubsampleAndSourceRegionParam() throws IOException {
|
||||
// NOTE: The "standard" (com.sun.imageio.plugin.*) ImageReaders pass
|
||||
// this test, so the test should be correct...
|
||||
ImageReader reader = createReader();
|
||||
@@ -716,7 +729,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadAsRenderedImageIndexNegative() {
|
||||
public void testReadAsRenderedImageIndexNegative() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -739,7 +752,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadAsRenderedImageIndexOutOfBounds() throws IIOException {
|
||||
public void testReadAsRenderedImageIndexOutOfBounds() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -766,7 +779,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadAsRenderedImageNoInput() {
|
||||
public void testReadAsRenderedImageNoInput() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
// Do not set input
|
||||
|
||||
@@ -788,7 +801,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadAsRenderedImage() {
|
||||
public void testReadAsRenderedImage() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -811,7 +824,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadAsRenderedImageWithDefaultParam() {
|
||||
public void testReadAsRenderedImageWithDefaultParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -834,7 +847,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultReadParam() {
|
||||
public void testGetDefaultReadParam() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
assertNotNull(param);
|
||||
@@ -842,7 +855,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFormatName() {
|
||||
public void testGetFormatName() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -858,7 +871,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMinIndex() {
|
||||
public void testGetMinIndex() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -874,7 +887,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMinIndexNoInput() {
|
||||
public void testGetMinIndexNoInput() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
int num = 0;
|
||||
|
||||
@@ -888,7 +901,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNumImages() {
|
||||
public void testGetNumImages() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -917,7 +930,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNumImagesNoInput() {
|
||||
public void testGetNumImagesNoInput() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
int num = -1;
|
||||
|
||||
@@ -945,7 +958,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWidth() {
|
||||
public void testGetWidth() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -962,7 +975,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWidthIndexOutOfBounds() {
|
||||
public void testGetWidthIndexOutOfBounds() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -983,13 +996,13 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWidthNoInput() {
|
||||
public void testGetWidthNoInput() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
|
||||
int width = 0;
|
||||
try {
|
||||
width = reader.getWidth(0);
|
||||
fail("Width read without imput");
|
||||
fail("Width read without input");
|
||||
}
|
||||
catch (IllegalStateException ignore) {
|
||||
}
|
||||
@@ -1001,7 +1014,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHeight() {
|
||||
public void testGetHeight() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1018,13 +1031,13 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHeightNoInput() {
|
||||
public void testGetHeightNoInput() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
|
||||
int height = 0;
|
||||
try {
|
||||
height = reader.getHeight(0);
|
||||
fail("height read without imput");
|
||||
fail("height read without input");
|
||||
}
|
||||
catch (IllegalStateException ignore) {
|
||||
}
|
||||
@@ -1036,7 +1049,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHeightIndexOutOfBounds() {
|
||||
public void testGetHeightIndexOutOfBounds() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1057,7 +1070,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAspectRatio() {
|
||||
public void testGetAspectRatio() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1075,7 +1088,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAspectRatioNoInput() {
|
||||
public void testGetAspectRatioNoInput() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
|
||||
float aspectRatio = 0f;
|
||||
@@ -1093,7 +1106,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAspectRatioIndexOutOfBounds() {
|
||||
public void testGetAspectRatioIndexOutOfBounds() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1114,13 +1127,13 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisposeBeforeRead() {
|
||||
public void testDisposeBeforeRead() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
reader.dispose(); // Just pass with no exceptions
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisposeAfterRead() {
|
||||
public void testDisposeAfterRead() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1128,21 +1141,21 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIIOReadProgressListener() {
|
||||
public void testAddIIOReadProgressListener() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
reader.addIIOReadProgressListener(mock(IIOReadProgressListener.class));
|
||||
reader.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIIOReadProgressListenerNull() {
|
||||
public void testAddIIOReadProgressListenerNull() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
reader.addIIOReadProgressListener(null);
|
||||
reader.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIIOReadProgressListenerCallbacks() {
|
||||
public void testAddIIOReadProgressListenerCallbacks() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1166,7 +1179,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleAddIIOReadProgressListenerCallbacks() {
|
||||
public void testMultipleAddIIOReadProgressListenerCallbacks() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1204,21 +1217,21 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOReadProgressListenerNull() {
|
||||
public void testRemoveIIOReadProgressListenerNull() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
reader.removeIIOReadProgressListener(null);
|
||||
reader.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOReadProgressListenerNone() {
|
||||
public void testRemoveIIOReadProgressListenerNone() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
reader.removeIIOReadProgressListener(mock(IIOReadProgressListener.class));
|
||||
reader.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOReadProgressListener() {
|
||||
public void testRemoveIIOReadProgressListener() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1240,7 +1253,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOReadProgressListenerMultiple() {
|
||||
public void testRemoveIIOReadProgressListenerMultiple() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1272,7 +1285,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAllIIOReadProgressListeners() {
|
||||
public void testRemoveAllIIOReadProgressListeners() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1295,7 +1308,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAllIIOReadProgressListenersMultiple() {
|
||||
public void testRemoveAllIIOReadProgressListenersMultiple() throws IOException {
|
||||
ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1322,7 +1335,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAbort() {
|
||||
public void testAbort() throws IOException {
|
||||
final ImageReader reader = createReader();
|
||||
TestData data = getTestData().get(0);
|
||||
reader.setInput(data.getInputStream());
|
||||
@@ -1336,7 +1349,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
// Create a listener that just makes the reader abort immediately...
|
||||
IIOReadProgressListener abortingListener = mock(IIOReadProgressListener.class, "Aborter");
|
||||
Answer<Void> abort = new Answer<Void>() {
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
public Void answer(InvocationOnMock invocation) {
|
||||
reader.abort();
|
||||
return null;
|
||||
}
|
||||
@@ -1387,7 +1400,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("ImageTypeSepcifier from getRawImageType should be in the iterator from getImageTypes", rawFound);
|
||||
assertTrue("ImageTypeSpecifier from getRawImageType should be in the iterator from getImageTypes", rawFound);
|
||||
}
|
||||
reader.dispose();
|
||||
}
|
||||
@@ -1569,7 +1582,6 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
reader.dispose();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Test
|
||||
public void testSetDestinationOffsetNull() throws IOException {
|
||||
final ImageReader reader = createReader();
|
||||
@@ -1620,7 +1632,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
assertEquals(expectedModel.getDataType(), resultModel.getDataType());
|
||||
assertEquals(expectedModel.getNumBands(), resultModel.getNumBands());
|
||||
assertEquals(expectedModel.getNumDataElements(), resultModel.getNumDataElements());
|
||||
assertTrue(Arrays.equals(expectedModel.getSampleSize(), resultModel.getSampleSize()));
|
||||
assertArrayEquals(expectedModel.getSampleSize(), resultModel.getSampleSize());
|
||||
assertEquals(expectedModel.getTransferType(), resultModel.getTransferType());
|
||||
for (int i = 0; i < expectedModel.getNumBands(); i++) {
|
||||
assertEquals(expectedModel.getSampleSize(i), resultModel.getSampleSize(i));
|
||||
@@ -1692,20 +1704,18 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
|
||||
@Ignore("TODO: Implement")
|
||||
@Test
|
||||
public void testSetDestinationBands() throws IOException {
|
||||
public void testSetDestinationBands() {
|
||||
throw new UnsupportedOperationException("Method testSetDestinationBands not implemented"); // TODO: Implement
|
||||
}
|
||||
|
||||
@Ignore("TODO: Implement")
|
||||
@Test
|
||||
public void testSetSourceBands() throws IOException {
|
||||
public void testSetSourceBands() {
|
||||
throw new UnsupportedOperationException("Method testSetDestinationBands not implemented"); // TODO: Implement
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderAndMetadataFormatNamesMatch() throws IOException {
|
||||
ImageReaderSpi provider = createProvider();
|
||||
|
||||
ImageReader reader = createReader();
|
||||
reader.setInput(getTestData().get(0).getInputStream());
|
||||
|
||||
@@ -1826,7 +1836,7 @@ public abstract class ImageReaderAbstractTest<T extends ImageReader> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + ": " + String.valueOf(input);
|
||||
return String.format("%s: %s", getClass().getSimpleName(), input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+37
-26
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.util;
|
||||
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@@ -39,12 +40,14 @@ import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.event.IIOWriteProgressListener;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
@@ -59,7 +62,7 @@ import static org.mockito.Mockito.*;
|
||||
* @author last modified by $Author: haku $
|
||||
* @version $Id: ImageReaderAbstractTestCase.java,v 1.0 18.nov.2004 17:38:33 haku Exp $
|
||||
*/
|
||||
public abstract class ImageWriterAbstractTest {
|
||||
public abstract class ImageWriterAbstractTest<T extends ImageWriter> {
|
||||
|
||||
// TODO: Move static block + getClassLoaderResource to common superclass for reader/writer test cases or delegate.
|
||||
|
||||
@@ -68,7 +71,16 @@ public abstract class ImageWriterAbstractTest {
|
||||
ImageIO.setUseCache(false);
|
||||
}
|
||||
|
||||
protected abstract ImageWriter createImageWriter();
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Class<T> writerClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
|
||||
protected final ImageWriterSpi provider = createProvider();
|
||||
|
||||
protected abstract ImageWriterSpi createProvider();
|
||||
|
||||
protected final T createWriter() throws IOException {
|
||||
return writerClass.cast(provider.createWriterInstance(null));
|
||||
}
|
||||
|
||||
protected abstract List<? extends RenderedImage> getTestData();
|
||||
|
||||
@@ -104,22 +116,22 @@ public abstract class ImageWriterAbstractTest {
|
||||
@Test
|
||||
public void testSetOutput() throws IOException {
|
||||
// Should just pass with no exceptions
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
assertNotNull(writer);
|
||||
writer.setOutput(ImageIO.createImageOutputStream(new ByteArrayOutputStream()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetOutputNull() {
|
||||
public void testSetOutputNull() throws IOException {
|
||||
// Should just pass with no exceptions
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
assertNotNull(writer);
|
||||
writer.setOutput(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrite() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
|
||||
for (RenderedImage testData : getTestData()) {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
@@ -136,10 +148,9 @@ public abstract class ImageWriterAbstractTest {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Test
|
||||
public void testWriteNull() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(buffer));
|
||||
|
||||
@@ -156,8 +167,8 @@ public abstract class ImageWriterAbstractTest {
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testWriteNoOutput() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testWriteNoOutput() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
|
||||
try {
|
||||
writer.write(getTestData(0));
|
||||
@@ -168,8 +179,8 @@ public abstract class ImageWriterAbstractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultWriteParam() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testGetDefaultWriteParam() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
ImageWriteParam param = writer.getDefaultWriteParam();
|
||||
assertNotNull("Default ImageWriteParam is null", param);
|
||||
}
|
||||
@@ -178,20 +189,20 @@ public abstract class ImageWriterAbstractTest {
|
||||
// TODO: Source region and subsampling at least
|
||||
|
||||
@Test
|
||||
public void testAddIIOWriteProgressListener() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testAddIIOWriteProgressListener() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
writer.addIIOWriteProgressListener(mock(IIOWriteProgressListener.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIIOWriteProgressListenerNull() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testAddIIOWriteProgressListenerNull() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
writer.addIIOWriteProgressListener(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIIOWriteProgressListenerCallbacks() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(buffer));
|
||||
|
||||
@@ -214,7 +225,7 @@ public abstract class ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testMultipleAddIIOWriteProgressListenerCallbacks() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(buffer));
|
||||
|
||||
@@ -250,20 +261,20 @@ public abstract class ImageWriterAbstractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOWriteProgressListenerNull() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testRemoveIIOWriteProgressListenerNull() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
writer.removeIIOWriteProgressListener(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOWriteProgressListenerNone() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testRemoveIIOWriteProgressListenerNone() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
writer.removeIIOWriteProgressListener(mock(IIOWriteProgressListener.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOWriteProgressListener() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(buffer));
|
||||
|
||||
@@ -284,7 +295,7 @@ public abstract class ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testRemoveIIOWriteProgressListenerMultiple() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(buffer));
|
||||
|
||||
@@ -316,7 +327,7 @@ public abstract class ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testRemoveAllIIOWriteProgressListeners() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(buffer));
|
||||
|
||||
@@ -339,7 +350,7 @@ public abstract class ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testRemoveAllIIOWriteProgressListenersMultiple() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(buffer));
|
||||
|
||||
|
||||
+17
-15
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.util;
|
||||
|
||||
import com.twelvemonkeys.imageio.color.ColorSpaces;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
@@ -39,7 +40,8 @@ import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.PixelInterleavedSampleModel;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class UInt32ImageTypeSpecifierTest {
|
||||
@@ -55,13 +57,13 @@ public class UInt32ImageTypeSpecifierTest {
|
||||
assertEquals(1, spec.getNumComponents());
|
||||
assertEquals(32, spec.getBitsPerBand(0));
|
||||
|
||||
assertThat(spec.getColorModel(), is(ComponentColorModel.class));
|
||||
assertThat(spec.getColorModel(), instanceOf(ComponentColorModel.class));
|
||||
assertFalse(spec.getColorModel().hasAlpha());
|
||||
assertFalse(spec.getColorModel().isAlphaPremultiplied());
|
||||
assertEquals(1, spec.getColorModel().getNumComponents());
|
||||
assertEquals(1, spec.getColorModel().getNumColorComponents());
|
||||
|
||||
assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class));
|
||||
assertThat(spec.getSampleModel(), instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertEquals(1, spec.getSampleModel().getNumBands());
|
||||
assertEquals(1, spec.getSampleModel().getNumDataElements());
|
||||
}
|
||||
@@ -74,13 +76,13 @@ public class UInt32ImageTypeSpecifierTest {
|
||||
assertEquals(32, spec.getBitsPerBand(0));
|
||||
assertEquals(32, spec.getBitsPerBand(1));
|
||||
|
||||
assertThat(spec.getColorModel(), is(ComponentColorModel.class));
|
||||
assertThat(spec.getColorModel(), instanceOf(ComponentColorModel.class));
|
||||
assertTrue(spec.getColorModel().hasAlpha());
|
||||
assertFalse(spec.getColorModel().isAlphaPremultiplied());
|
||||
assertEquals(2, spec.getColorModel().getNumComponents());
|
||||
assertEquals(1, spec.getColorModel().getNumColorComponents());
|
||||
|
||||
assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class));
|
||||
assertThat(spec.getSampleModel(), instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertEquals(2, spec.getSampleModel().getNumBands());
|
||||
assertEquals(2, spec.getSampleModel().getNumDataElements());
|
||||
}
|
||||
@@ -95,13 +97,13 @@ public class UInt32ImageTypeSpecifierTest {
|
||||
assertEquals(32, spec.getBitsPerBand(1));
|
||||
assertEquals(32, spec.getBitsPerBand(2));
|
||||
|
||||
assertThat(spec.getColorModel(), is(ComponentColorModel.class));
|
||||
assertThat(spec.getColorModel(), instanceOf(ComponentColorModel.class));
|
||||
assertFalse(spec.getColorModel().hasAlpha());
|
||||
assertFalse(spec.getColorModel().isAlphaPremultiplied());
|
||||
assertEquals(3, spec.getColorModel().getNumComponents());
|
||||
assertEquals(3, spec.getColorModel().getNumColorComponents());
|
||||
|
||||
assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class));
|
||||
assertThat(spec.getSampleModel(), instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertEquals(3, spec.getSampleModel().getNumBands());
|
||||
assertEquals(3, spec.getSampleModel().getNumDataElements());
|
||||
}
|
||||
@@ -116,13 +118,13 @@ public class UInt32ImageTypeSpecifierTest {
|
||||
assertEquals(32, spec.getBitsPerBand(2));
|
||||
assertEquals(32, spec.getBitsPerBand(3));
|
||||
|
||||
assertThat(spec.getColorModel(), is(ComponentColorModel.class));
|
||||
assertThat(spec.getColorModel(), instanceOf(ComponentColorModel.class));
|
||||
assertTrue(spec.getColorModel().hasAlpha());
|
||||
assertFalse(spec.getColorModel().isAlphaPremultiplied());
|
||||
assertEquals(4, spec.getColorModel().getNumComponents());
|
||||
assertEquals(3, spec.getColorModel().getNumColorComponents());
|
||||
|
||||
assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class));
|
||||
assertThat(spec.getSampleModel(), instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertEquals(4, spec.getSampleModel().getNumBands());
|
||||
assertEquals(4, spec.getSampleModel().getNumDataElements());
|
||||
}
|
||||
@@ -137,13 +139,13 @@ public class UInt32ImageTypeSpecifierTest {
|
||||
assertEquals(32, spec.getBitsPerBand(2));
|
||||
assertEquals(32, spec.getBitsPerBand(3));
|
||||
|
||||
assertThat(spec.getColorModel(), is(ComponentColorModel.class));
|
||||
assertThat(spec.getColorModel(), instanceOf(ComponentColorModel.class));
|
||||
assertTrue(spec.getColorModel().hasAlpha());
|
||||
assertTrue(spec.getColorModel().isAlphaPremultiplied());
|
||||
assertEquals(4, spec.getColorModel().getNumComponents());
|
||||
assertEquals(3, spec.getColorModel().getNumColorComponents());
|
||||
|
||||
assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class));
|
||||
assertThat(spec.getSampleModel(), instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertEquals(4, spec.getSampleModel().getNumBands());
|
||||
assertEquals(4, spec.getSampleModel().getNumDataElements());
|
||||
}
|
||||
@@ -159,13 +161,13 @@ public class UInt32ImageTypeSpecifierTest {
|
||||
assertEquals(32, spec.getBitsPerBand(2));
|
||||
assertEquals(32, spec.getBitsPerBand(3));
|
||||
|
||||
assertThat(spec.getColorModel(), is(ComponentColorModel.class));
|
||||
assertThat(spec.getColorModel(), instanceOf(ComponentColorModel.class));
|
||||
assertFalse(spec.getColorModel().hasAlpha());
|
||||
assertFalse(spec.getColorModel().isAlphaPremultiplied());
|
||||
assertEquals(4, spec.getColorModel().getNumComponents());
|
||||
assertEquals(4, spec.getColorModel().getNumColorComponents());
|
||||
|
||||
assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class));
|
||||
assertThat(spec.getSampleModel(), instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertEquals(4, spec.getSampleModel().getNumBands());
|
||||
assertEquals(4, spec.getSampleModel().getNumDataElements());
|
||||
}
|
||||
@@ -181,13 +183,13 @@ public class UInt32ImageTypeSpecifierTest {
|
||||
assertEquals(32, spec.getBitsPerBand(3));
|
||||
assertEquals(32, spec.getBitsPerBand(4));
|
||||
|
||||
assertThat(spec.getColorModel(), is(ComponentColorModel.class));
|
||||
assertThat(spec.getColorModel(), instanceOf(ComponentColorModel.class));
|
||||
assertTrue(spec.getColorModel().hasAlpha());
|
||||
assertFalse(spec.getColorModel().isAlphaPremultiplied());
|
||||
assertEquals(5, spec.getColorModel().getNumComponents());
|
||||
assertEquals(4, spec.getColorModel().getNumColorComponents());
|
||||
|
||||
assertThat(spec.getSampleModel(), is(PixelInterleavedSampleModel.class));
|
||||
assertThat(spec.getSampleModel(), instanceOf(PixelInterleavedSampleModel.class));
|
||||
assertEquals(5, spec.getSampleModel().getNumBands());
|
||||
assertEquals(5, spec.getSampleModel().getNumDataElements());
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-hdr</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: HDR plugin</name>
|
||||
@@ -21,6 +21,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
|
||||
+4
-14
@@ -46,26 +46,16 @@ import java.util.List;
|
||||
* @version $Id: TGAImageReaderTest.java,v 1.0 03.07.14 22:28 haraldk Exp$
|
||||
*/
|
||||
public class HDRImageReaderTest extends ImageReaderAbstractTest<HDRImageReader> {
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
new TestData(getClassLoaderResource("/hdr/memorial_o876.hdr"), new Dimension(512, 768))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new HDRImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<HDRImageReader> getReaderClass() {
|
||||
return HDRImageReader.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HDRImageReader createReader() {
|
||||
return new HDRImageReader(createProvider());
|
||||
protected List<TestData> getTestData() {
|
||||
return Collections.singletonList(
|
||||
new TestData(getClassLoaderResource("/hdr/memorial_o876.hdr"), new Dimension(512, 768))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.twelvemonkeys.imageio.plugins.hdr.tonemap;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
public class DefaultToneMapperTest {
|
||||
|
||||
private final DefaultToneMapper mapper = new DefaultToneMapper();
|
||||
|
||||
@Test
|
||||
public void testMap0() {
|
||||
float[] rgb = {0};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{0}, rgb, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMap1() {
|
||||
float[] rgb = {1};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{0.5f}, rgb, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapMax() {
|
||||
float[] rgb = {Float.MAX_VALUE};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{1}, rgb, 0);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.twelvemonkeys.imageio.plugins.hdr.tonemap;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
public class GammaToneMapperTest {
|
||||
private final GammaToneMapper mapper = new GammaToneMapper();
|
||||
|
||||
@Test
|
||||
public void testMap0() {
|
||||
float[] rgb = {0};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{0}, rgb, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMap1() {
|
||||
float[] rgb = {1};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{0.5f}, rgb, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMap16() {
|
||||
float[] rgb = {15.999999f};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{1}, rgb, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapMax() {
|
||||
float[] rgb = {Float.MAX_VALUE};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{1}, rgb, 0);
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.twelvemonkeys.imageio.plugins.hdr.tonemap;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
public class NullToneMapperTest {
|
||||
private final NullToneMapper mapper = new NullToneMapper();
|
||||
|
||||
@Test
|
||||
public void testMap0() {
|
||||
float[] rgb = {0};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{0}, rgb, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMap1() {
|
||||
float[] rgb = {1};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{1}, rgb, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapMax() {
|
||||
float[] rgb = {Float.MAX_VALUE};
|
||||
mapper.map(rgb);
|
||||
assertArrayEquals(new float[]{Float.MAX_VALUE}, rgb, 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-icns</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: ICNS plugin</name>
|
||||
@@ -19,6 +19,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+7
-17
@@ -31,10 +31,10 @@
|
||||
package com.twelvemonkeys.imageio.plugins.icns;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
@@ -49,7 +49,12 @@ import java.util.List;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: ICNSImageReaderTest.java,v 1.0 25.10.11 18:44 haraldk Exp$
|
||||
*/
|
||||
public class ICNSImageReaderTest extends ImageReaderAbstractTest {
|
||||
public class ICNSImageReaderTest extends ImageReaderAbstractTest<ICNSImageReader> {
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new ICNSImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
@@ -105,21 +110,6 @@ public class ICNSImageReaderTest extends ImageReaderAbstractTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new ICNSImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageReader createReader() {
|
||||
return new ICNSImageReader();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class getReaderClass() {
|
||||
return ICNSImageReader.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("icns");
|
||||
|
||||
+13
-13
@@ -31,11 +31,13 @@
|
||||
package com.twelvemonkeys.imageio.plugins.icns;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
@@ -53,13 +55,11 @@ import static org.junit.Assert.assertTrue;
|
||||
* @author last modified by $Author: harald.kuhr$
|
||||
* @version $Id: ICNSImageWriterTest.java,v 1.0 25/08/2018 harald.kuhr Exp$
|
||||
*/
|
||||
public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
|
||||
private final ICNSImageWriterSpi provider = new ICNSImageWriterSpi();
|
||||
public class ICNSImageWriterTest extends ImageWriterAbstractTest<ICNSImageWriter> {
|
||||
|
||||
@Override
|
||||
protected ImageWriter createImageWriter() {
|
||||
return provider.createWriterInstance(null);
|
||||
protected ImageWriterSpi createProvider() {
|
||||
return new ICNSImageWriterSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +81,7 @@ public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testWriteNonSquare() throws IOException {
|
||||
// ICNS only supports square icons (except some arcane 16x12 we don't currently support)
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
try (ImageOutputStream stream = ImageIO.createImageOutputStream(new ByteArrayOutputStream())) {
|
||||
|
||||
writer.setOutput(stream);
|
||||
@@ -97,7 +97,7 @@ public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testWriteBadSize() throws IOException {
|
||||
// ICNS only supports sizes in multiples of 2 (16, 32, 64, ..., 1024 + 48 and 96)
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
try (ImageOutputStream stream = ImageIO.createImageOutputStream(new ByteArrayOutputStream())) {
|
||||
|
||||
writer.setOutput(stream);
|
||||
@@ -111,8 +111,8 @@ public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSequencesSupported() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testSequencesSupported() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
try {
|
||||
assertTrue(writer.canWriteSequence());
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testWriteSequenceNotStarted() throws IOException {
|
||||
// ICNS only supports sizes in multiples of 2 (16, 32, 64, ..., 1024 + 48 and 96)
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
try (ImageOutputStream stream = ImageIO.createImageOutputStream(new ByteArrayOutputStream())) {
|
||||
|
||||
writer.setOutput(stream);
|
||||
@@ -141,7 +141,7 @@ public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testEndSequenceNotStarted() throws IOException {
|
||||
// ICNS only supports sizes in multiples of 2 (16, 32, 64, ..., 1024 + 48 and 96)
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
try (ImageOutputStream stream = ImageIO.createImageOutputStream(new ByteArrayOutputStream())) {
|
||||
|
||||
writer.setOutput(stream);
|
||||
@@ -155,7 +155,7 @@ public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testPrepareSequenceAlreadyStarted() throws IOException {
|
||||
// ICNS only supports sizes in multiples of 2 (16, 32, 64, ..., 1024 + 48 and 96)
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
try (ImageOutputStream stream = ImageIO.createImageOutputStream(new ByteArrayOutputStream())) {
|
||||
|
||||
writer.setOutput(stream);
|
||||
@@ -169,7 +169,7 @@ public class ICNSImageWriterTest extends ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testWriteSequence() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
|
||||
try (ImageOutputStream stream = ImageIO.createImageOutputStream(output)) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-iff</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: IFF plugin</name>
|
||||
@@ -22,6 +22,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+10
-8
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.iff;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -54,6 +55,12 @@ import static org.junit.Assert.*;
|
||||
* @version $Id: IFFImageReaderTestCase.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
|
||||
*/
|
||||
public class IFFImageReaderTest extends ImageReaderAbstractTest<IFFImageReader> {
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new IFFImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
// 32 bit - Ok
|
||||
@@ -85,22 +92,17 @@ public class IFFImageReaderTest extends ImageReaderAbstractTest<IFFImageReader>
|
||||
);
|
||||
}
|
||||
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new IFFImageReaderSpi();
|
||||
}
|
||||
|
||||
protected Class<IFFImageReader> getReaderClass() {
|
||||
return IFFImageReader.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("iff");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSuffixes() {
|
||||
return Arrays.asList("iff", "ilbm", "ham", "ham8", "lbm");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getMIMETypes() {
|
||||
return Arrays.asList("image/iff", "image/x-iff");
|
||||
}
|
||||
|
||||
+7
-9
@@ -32,10 +32,12 @@ package com.twelvemonkeys.imageio.plugins.iff;
|
||||
|
||||
import com.twelvemonkeys.image.MonochromeColorModel;
|
||||
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.awt.color.ColorSpace;
|
||||
@@ -56,12 +58,10 @@ import static org.junit.Assert.*;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: JPEG2000ImageWriterTest.java,v 1.0 20.01.12 12:19 haraldk Exp$
|
||||
*/
|
||||
public class IFFImageWriterTest extends ImageWriterAbstractTest {
|
||||
private final IFFImageWriterSpi provider = new IFFImageWriterSpi();
|
||||
|
||||
public class IFFImageWriterTest extends ImageWriterAbstractTest<IFFImageWriter> {
|
||||
@Override
|
||||
protected ImageWriter createImageWriter() {
|
||||
return new IFFImageWriter(provider);
|
||||
protected ImageWriterSpi createProvider() {
|
||||
return new IFFImageWriterSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +81,7 @@ public class IFFImageWriterTest extends ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testWriteReadCompare() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
|
||||
List<? extends RenderedImage> testData = getTestData();
|
||||
|
||||
@@ -116,9 +116,7 @@ public class IFFImageWriterTest extends ImageWriterAbstractTest {
|
||||
assertSameData(original, written);
|
||||
}
|
||||
catch (IOException e) {
|
||||
AssertionError fail = new AssertionError("Failure writing test data " + i + " " + e);
|
||||
fail.initCause(e);
|
||||
throw fail;
|
||||
throw new AssertionError("Failure writing test data " + i + " " + e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: JPEG plugin</name>
|
||||
@@ -21,6 +21,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
|
||||
+50
-40
@@ -30,6 +30,37 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.jpeg;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.image.*;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.event.IIOReadUpdateListener;
|
||||
import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.color.ColorSpaces;
|
||||
import com.twelvemonkeys.imageio.color.YCbCrConverter;
|
||||
@@ -49,24 +80,6 @@ import com.twelvemonkeys.imageio.util.ProgressListenerBase;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import com.twelvemonkeys.xml.XMLSerializer;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.event.IIOReadUpdateListener;
|
||||
import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A JPEG {@code ImageReader} implementation based on the JRE {@code JPEGImageReader},
|
||||
* that adds support and properly handles cases where the JRE version throws exceptions.
|
||||
@@ -123,8 +136,6 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
private ImageReader thumbnailReader;
|
||||
private List<ThumbnailReader> thumbnails;
|
||||
|
||||
private JPEGImage10MetadataCleaner metadataCleaner;
|
||||
|
||||
/** Cached list of JPEG segments we filter from the underlying stream */
|
||||
private List<Segment> segments;
|
||||
|
||||
@@ -158,8 +169,6 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
thumbnailReader.reset();
|
||||
}
|
||||
|
||||
metadataCleaner = null;
|
||||
|
||||
installListeners();
|
||||
}
|
||||
|
||||
@@ -469,15 +478,12 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
// We'll need a read param
|
||||
Rectangle origSourceRegion;
|
||||
if (param == null) {
|
||||
param = delegate.getDefaultReadParam();
|
||||
origSourceRegion = null;
|
||||
}
|
||||
else {
|
||||
origSourceRegion = param.getSourceRegion();
|
||||
}
|
||||
|
||||
Rectangle origSourceRegion = param.getSourceRegion();
|
||||
|
||||
Rectangle srcRegion = new Rectangle();
|
||||
Rectangle dstRegion = new Rectangle();
|
||||
computeRegions(param, origWidth, origHeight, image, srcRegion, dstRegion);
|
||||
@@ -903,16 +909,16 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
|
||||
if (!exifSegments.isEmpty()) {
|
||||
Application exif = exifSegments.get(0);
|
||||
InputStream data = exif.data();
|
||||
int offset = exif.identifier.length() + 2; // Incl. pad
|
||||
|
||||
if (data.read() == -1) { // Read pad
|
||||
if (exif.data.length <= offset) {
|
||||
processWarningOccurred("Exif chunk has no data.");
|
||||
}
|
||||
else {
|
||||
ImageInputStream stream = new MemoryCacheImageInputStream(data);
|
||||
return (CompoundDirectory) new TIFFReader().read(stream);
|
||||
|
||||
// TODO: Directory offset of thumbnail is wrong/relative to container stream, causing trouble for the TIFFReader...
|
||||
// TODO: Consider returning ByteArrayImageInputStream from Segment.data()
|
||||
try (ImageInputStream stream = new ByteArrayImageInputStream(exif.data, offset, exif.data.length - offset)) {
|
||||
return (CompoundDirectory) new TIFFReader().read(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,13 +1129,13 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
Application exif = exifSegments.get(0);
|
||||
|
||||
// Identifier is "Exif\0" + 1 byte pad
|
||||
int offset = exif.identifier.length() + 2;
|
||||
int dataOffset = exif.identifier.length() + 2;
|
||||
|
||||
if (exif.data.length <= offset) {
|
||||
if (exif.data.length <= dataOffset) {
|
||||
processWarningOccurred("Exif chunk has no data.");
|
||||
}
|
||||
else {
|
||||
ImageInputStream stream = new ByteArrayImageInputStream(exif.data, offset, exif.data.length - offset);
|
||||
ImageInputStream stream = new ByteArrayImageInputStream(exif.data, dataOffset, exif.data.length - dataOffset);
|
||||
CompoundDirectory exifMetadata = (CompoundDirectory) new TIFFReader().read(stream);
|
||||
|
||||
if (exifMetadata.directoryCount() == 2) {
|
||||
@@ -1140,14 +1146,18 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
int compression = compressionEntry == null ? 6 : ((Number) compressionEntry.getValue()).intValue();
|
||||
|
||||
if (compression == 6) {
|
||||
if (ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT) != null) {
|
||||
Entry jpegLength = ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
|
||||
Entry jpegOffEntry = ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT);
|
||||
if (jpegOffEntry != null) {
|
||||
Entry jpegLenEntry = ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
|
||||
|
||||
if ((jpegLength == null || ((Number) jpegLength.getValue()).longValue() > 0)) {
|
||||
// Test if Exif thumbnail is contained within the Exif segment (offset + length <= segment.length)
|
||||
long jpegOffset = ((Number) jpegOffEntry.getValue()).longValue();
|
||||
long jpegLength = jpegLenEntry != null ? ((Number) jpegLenEntry.getValue()).longValue() : -1;
|
||||
if (jpegLength > 0 && jpegOffset + jpegLength <= stream.length()) {
|
||||
thumbnails.add(new EXIFThumbnailReader(thumbnailProgressDelegator, getThumbnailReader(), 0, thumbnails.size(), ifd1, stream));
|
||||
}
|
||||
else {
|
||||
processWarningOccurred("EXIF IFD with empty (zero-length) thumbnail");
|
||||
processWarningOccurred("EXIF IFD with empty or incomplete JPEG thumbnail");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+17
-33
@@ -32,6 +32,7 @@ package com.twelvemonkeys.imageio.plugins.jpeg;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
|
||||
import org.hamcrest.core.IsInstanceOf;
|
||||
import org.junit.Test;
|
||||
import org.mockito.internal.matchers.GreaterThan;
|
||||
@@ -60,6 +61,7 @@ import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static com.twelvemonkeys.imageio.util.IIOUtil.lookupProviderByName;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeNoException;
|
||||
import static org.junit.Assume.assumeNotNull;
|
||||
@@ -77,7 +79,10 @@ import static org.mockito.Mockito.*;
|
||||
*/
|
||||
public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader> {
|
||||
|
||||
private static final JPEGImageReaderSpi SPI = new JPEGImageReaderSpi(lookupDelegateProvider());
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new JPEGImageReaderSpi(lookupDelegateProvider());
|
||||
}
|
||||
|
||||
private static ImageReaderSpi lookupDelegateProvider() {
|
||||
return lookupProviderByName(IIORegistry.getDefaultInstance(), "com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi", ImageReaderSpi.class);
|
||||
@@ -133,26 +138,6 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
// More test data in specific tests below
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return SPI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JPEGImageReader createReader() {
|
||||
try {
|
||||
return (JPEGImageReader) SPI.createReaderInstance();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<JPEGImageReader> getReaderClass() {
|
||||
return JPEGImageReader.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowsNullRawImageType() {
|
||||
return true;
|
||||
@@ -205,7 +190,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertJPEGPixelsEqual(byte[] expected, byte[] actual, int actualOffset) {
|
||||
private static void assertJPEGPixelsEqual(byte[] expected, byte[] actual, @SuppressWarnings("SameParameterValue") int actualOffset) {
|
||||
for (int i = 0; i < expected.length; i++) {
|
||||
assertEquals(String.format("Difference in pixel %d", i), expected[i], actual[i + actualOffset], 5);
|
||||
}
|
||||
@@ -550,7 +535,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenReadRasterAfterGetMetadataException() {
|
||||
public void testBrokenReadRasterAfterGetMetadataException() throws IOException {
|
||||
// See issue #107, from PDFBox team
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
@@ -585,7 +570,6 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
public void testSPIRecognizesBrokenJPEG() throws IOException {
|
||||
// TODO: There's a bug in com.sun.imageio.plugins.png.PNGImageReaderSpi.canDecode
|
||||
// causing files < 8 bytes to not be recognized as anything...
|
||||
ImageReaderSpi provider = createProvider();
|
||||
for (TestData data : getBrokenTestData()) {
|
||||
assertTrue(data.toString(), provider.canDecodeInput(data.getInputStream()));
|
||||
}
|
||||
@@ -594,7 +578,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
// TODO: Consider wrapping the delegate in JPEGImageReader with methods that don't throw
|
||||
// runtime exceptions, and instead throw IIOException?
|
||||
@Test
|
||||
public void testBrokenGetRawImageType() {
|
||||
public void testBrokenGetRawImageType() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
try {
|
||||
@@ -620,7 +604,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
|
||||
@Test(timeout = 200)
|
||||
public void testBrokenGetRawImageTypeIgnoreMetadata() {
|
||||
public void testBrokenGetRawImageTypeIgnoreMetadata() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
try {
|
||||
@@ -646,7 +630,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenGetImageTypes() {
|
||||
public void testBrokenGetImageTypes() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
try {
|
||||
@@ -672,7 +656,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
|
||||
@Test(timeout = 200)
|
||||
public void testBrokenGetImageTypesIgnoreMetadata() {
|
||||
public void testBrokenGetImageTypesIgnoreMetadata() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
try {
|
||||
@@ -698,7 +682,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenRead() {
|
||||
public void testBrokenRead() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
try {
|
||||
@@ -724,7 +708,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenGetDimensions() {
|
||||
public void testBrokenGetDimensions() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
try {
|
||||
@@ -753,7 +737,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenGetImageMetadata() {
|
||||
public void testBrokenGetImageMetadata() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
|
||||
try {
|
||||
@@ -1504,9 +1488,9 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
throw new AssertionError(String.format("Reading metadata failed for %s image %s: %s", testData, i, e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
catch (IIOException ignore) {
|
||||
catch (IIOException warn) {
|
||||
// The reference reader will fail on certain images, we'll just ignore that
|
||||
System.err.println(String.format("WARNING: Reading reference metadata failed for %s image %s: %s", testData, i, ignore.getMessage()));
|
||||
System.err.printf("WARNING: Reading reference metadata failed for %s image %s: %s%n", testData, i, warn.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+87
-15
@@ -33,6 +33,7 @@ package com.twelvemonkeys.imageio.plugins.jpeg;
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
@@ -47,17 +48,23 @@ import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageOutputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* JPEGImageWriterTest
|
||||
@@ -66,22 +73,14 @@ import static org.junit.Assert.assertNotNull;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: JPEGImageWriterTest.java,v 1.0 06.02.12 17:05 haraldk Exp$
|
||||
*/
|
||||
public class JPEGImageWriterTest extends ImageWriterAbstractTest {
|
||||
|
||||
private static final JPEGImageWriterSpi SPI = new JPEGImageWriterSpi(lookupDelegateProvider());
|
||||
|
||||
public class JPEGImageWriterTest extends ImageWriterAbstractTest<JPEGImageWriter> {
|
||||
private static ImageWriterSpi lookupDelegateProvider() {
|
||||
return IIOUtil.lookupProviderByName(IIORegistry.getDefaultInstance(), "com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi", ImageWriterSpi.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageWriter createImageWriter() {
|
||||
try {
|
||||
return SPI.createWriterInstance();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
protected ImageWriterSpi createProvider() {
|
||||
return new JPEGImageWriterSpi(lookupDelegateProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,14 +96,18 @@ public class JPEGImageWriterTest extends ImageWriterAbstractTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReaderForWriter() {
|
||||
ImageWriter writer = createImageWriter();
|
||||
public void testReaderForWriter() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
ImageReader reader = ImageIO.getImageReader(writer);
|
||||
assertNotNull(reader);
|
||||
assertEquals(writer.getClass().getPackage(), reader.getClass().getPackage());
|
||||
}
|
||||
|
||||
private ByteArrayOutputStream transcode(final ImageReader reader, final URL resource, final ImageWriter writer, int outCSType) throws IOException {
|
||||
return transcode(reader, resource, writer, outCSType, true);
|
||||
}
|
||||
|
||||
private ByteArrayOutputStream transcode(final ImageReader reader, final URL resource, final ImageWriter writer, int outCSType, boolean embedICCProfile) throws IOException {
|
||||
try (ImageInputStream input = ImageIO.createImageInputStream(resource)) {
|
||||
reader.setInput(input);
|
||||
ImageTypeSpecifier specifier = null;
|
||||
@@ -125,6 +128,14 @@ public class JPEGImageWriterTest extends ImageWriterAbstractTest {
|
||||
readParam.setDestinationType(specifier);
|
||||
IIOImage image = reader.readAll(0, readParam);
|
||||
|
||||
if (!embedICCProfile) {
|
||||
// Get rid of the color model/icc profile
|
||||
ColorSpace fakeCS = mock(ColorSpace.class);
|
||||
when(fakeCS.getType()).thenReturn(ColorSpace.TYPE_CMYK);
|
||||
when(fakeCS.getNumComponents()).thenReturn(4);
|
||||
specifier = new ImageTypeSpecifier(new ComponentColorModel(fakeCS, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE), image.getRenderedImage().getSampleModel());
|
||||
}
|
||||
|
||||
// Write it back
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024);
|
||||
try (ImageOutputStream output = new MemoryCacheImageOutputStream(bytes)) {
|
||||
@@ -140,7 +151,7 @@ public class JPEGImageWriterTest extends ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testTranscodeWithMetadataRGBtoRGB() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ImageReader reader = ImageIO.getImageReader(writer);
|
||||
|
||||
ByteArrayOutputStream stream = transcode(reader, getClassLoaderResource("/jpeg/jfif-jfxx-thumbnail-olympus-d320l.jpg"), writer, ColorSpace.TYPE_RGB);
|
||||
@@ -151,11 +162,18 @@ public class JPEGImageWriterTest extends ImageWriterAbstractTest {
|
||||
reader.setInput(new ByteArrayImageInputStream(stream.toByteArray()));
|
||||
BufferedImage image = reader.read(0);
|
||||
assertNotNull(image);
|
||||
|
||||
// Test color space type RGB (encoded as YCbCr) in standard metadata
|
||||
IIOMetadata metadata = reader.getImageMetadata(0);
|
||||
IIOMetadataNode standard = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||
NodeList colorSpaceType = standard.getElementsByTagName("ColorSpaceType");
|
||||
assertEquals(1, colorSpaceType.getLength());
|
||||
assertEquals("YCbCr", ((IIOMetadataNode) colorSpaceType.item(0)).getAttribute("name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTranscodeWithMetadataCMYKtoCMYK() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
ImageReader reader = ImageIO.getImageReader(writer);
|
||||
|
||||
ByteArrayOutputStream stream = transcode(reader, getClassLoaderResource("/jpeg/cmyk-sample-multiple-chunk-icc.jpg"), writer, ColorSpace.TYPE_CMYK);
|
||||
@@ -168,11 +186,65 @@ public class JPEGImageWriterTest extends ImageWriterAbstractTest {
|
||||
assertEquals(100, image.getWidth());
|
||||
assertEquals(100, image.getHeight());
|
||||
|
||||
// Test color space type CMYK in standard metadata
|
||||
IIOMetadata metadata = reader.getImageMetadata(0);
|
||||
IIOMetadataNode standard = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||
NodeList colorSpaceType = standard.getElementsByTagName("ColorSpaceType");
|
||||
assertEquals(1, colorSpaceType.getLength());
|
||||
assertEquals("CMYK", ((IIOMetadataNode) colorSpaceType.item(0)).getAttribute("name"));
|
||||
|
||||
// Test APP2/ICC_PROFILE segments form native metadata
|
||||
IIOMetadataNode nativeMeta = (IIOMetadataNode) metadata.getAsTree(JPEGImage10Metadata.JAVAX_IMAGEIO_JPEG_IMAGE_1_0);
|
||||
NodeList unknown = nativeMeta.getElementsByTagName("unknown");
|
||||
assertEquals(11, unknown.getLength()); // We write longer segments than the original, so we get less segments
|
||||
|
||||
ByteArrayOutputStream iccSegments = new ByteArrayOutputStream(1024 * 1024);
|
||||
|
||||
for (int i = 0; i < unknown.getLength(); i++) {
|
||||
IIOMetadataNode node = (IIOMetadataNode) unknown.item(i);
|
||||
byte[] data = (byte[]) node.getUserObject();
|
||||
|
||||
// 226 -> E2, FFE2 -> APP2 marker, ICC_PROFILE
|
||||
String markerId = "ICC_PROFILE";
|
||||
if (node.getAttribute("MarkerTag").equals("226")
|
||||
&& markerId.equals(new String(data, 0, markerId.length(), StandardCharsets.US_ASCII))) {
|
||||
int offset = markerId.length() + 3; // ICC_PROFILE + null + index + count
|
||||
iccSegments.write(Arrays.copyOfRange(data, offset, data.length));
|
||||
}
|
||||
}
|
||||
|
||||
ICC_Profile profile = ICC_Profile.getInstance(iccSegments.toByteArray());
|
||||
assertNotNull(profile); // Assumption, we either have a valid profile, or getInstance blew up...
|
||||
assertEquals(ColorSpace.TYPE_CMYK, profile.getColorSpaceType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTranscodeWithMetadataCMYKtoCMYKNoProfile() throws IOException {
|
||||
ImageWriter writer = createWriter();
|
||||
ImageReader reader = ImageIO.getImageReader(writer);
|
||||
|
||||
// TODO: Add flag to allow removing the ICC profile from image
|
||||
ByteArrayOutputStream stream = transcode(reader, getClassLoaderResource("/jpeg/cmyk-sample-multiple-chunk-icc.jpg"), writer, ColorSpace.TYPE_CMYK, false);
|
||||
|
||||
reader.reset();
|
||||
reader.setInput(new ByteArrayImageInputStream(stream.toByteArray()));
|
||||
|
||||
BufferedImage image = reader.read(0);
|
||||
assertNotNull(image);
|
||||
assertEquals(100, image.getWidth());
|
||||
assertEquals(100, image.getHeight());
|
||||
|
||||
// Test color space type CMYK in standard metadata
|
||||
IIOMetadata metadata = reader.getImageMetadata(0);
|
||||
IIOMetadataNode standard = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||
NodeList colorSpaceType = standard.getElementsByTagName("ColorSpaceType");
|
||||
assertEquals(1, colorSpaceType.getLength());
|
||||
assertEquals("CMYK", ((IIOMetadataNode) colorSpaceType.item(0)).getAttribute("name"));
|
||||
|
||||
// Test APP2/ICC_PROFILE segments form native metadata
|
||||
IIOMetadataNode nativeMeta = (IIOMetadataNode) metadata.getAsTree(JPEGImage10Metadata.JAVAX_IMAGEIO_JPEG_IMAGE_1_0);
|
||||
NodeList unknown = nativeMeta.getElementsByTagName("unknown");
|
||||
assertEquals(0, unknown.getLength());
|
||||
}
|
||||
|
||||
// TODO: YCCK
|
||||
|
||||
+4
-1
@@ -34,6 +34,7 @@ import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegment;
|
||||
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegmentUtil;
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.internal.matchers.LessOrEqual;
|
||||
|
||||
@@ -46,7 +47,9 @@ import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* JPEGSegmentImageInputStreamTest
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>imageio-metadata</artifactId>
|
||||
@@ -21,6 +21,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+12
-8
@@ -30,12 +30,12 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.metadata;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import com.twelvemonkeys.util.CollectionUtil;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import com.twelvemonkeys.util.CollectionUtil;
|
||||
|
||||
/**
|
||||
* AbstractEntry
|
||||
*
|
||||
@@ -84,17 +84,21 @@ public abstract class AbstractEntry implements Entry {
|
||||
}
|
||||
|
||||
public String getValueAsString() {
|
||||
if (valueCount() > 1) {
|
||||
if (valueCount() < 16) {
|
||||
int count = valueCount();
|
||||
|
||||
if (count == 0 && value != null && value.getClass().isArray() && Array.getLength(value) == 0) {
|
||||
return "";
|
||||
}
|
||||
if (count > 1) {
|
||||
if (count < 16) {
|
||||
return arrayToString(value);
|
||||
}
|
||||
else {
|
||||
String first = arrayToString(CollectionUtil.subArray(value, 0, 4));
|
||||
String last = arrayToString(CollectionUtil.subArray(value, valueCount() - 4, 4));
|
||||
return String.format("%s ... %s (%d)", first.substring(0, first.length() - 1), last.substring(1), valueCount());
|
||||
String last = arrayToString(CollectionUtil.subArray(value, count - 4, 4));
|
||||
return String.format("%s ... %s (%d)", first.substring(0, first.length() - 1), last.substring(1), count);
|
||||
}
|
||||
}
|
||||
|
||||
if (value != null && value.getClass().isArray() && Array.getLength(value) == 1) {
|
||||
return String.valueOf(Array.get(value, 0));
|
||||
}
|
||||
|
||||
-1
@@ -41,7 +41,6 @@ package com.twelvemonkeys.imageio.metadata.exif;
|
||||
*
|
||||
* @deprecated Use com.twelvemonkeys.imageio.metadata.tiff.Rational instead.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public final class Rational extends Number implements Comparable<Rational> {
|
||||
private final com.twelvemonkeys.imageio.metadata.tiff.Rational delegate;
|
||||
|
||||
|
||||
+2
-2
@@ -48,7 +48,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
@@ -154,7 +154,7 @@ public final class JPEGSegmentUtil {
|
||||
}
|
||||
|
||||
static String asAsciiString(final byte[] data, final int offset, final int length) {
|
||||
return new String(data, offset, length, Charset.forName("ascii"));
|
||||
return new String(data, offset, length, StandardCharsets.US_ASCII);
|
||||
}
|
||||
|
||||
static void readSOI(final ImageInputStream stream) throws IOException {
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ public final class Rational extends Number implements Comparable<Rational> {
|
||||
double thisVal = doubleValue();
|
||||
double otherVal = pOther.doubleValue();
|
||||
|
||||
return thisVal < otherVal ? -1 : thisVal == otherVal ? 0 : 1;
|
||||
return Double.compare(thisVal, otherVal);
|
||||
}
|
||||
|
||||
/// Object overrides
|
||||
|
||||
+27
-25
@@ -30,15 +30,8 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.metadata.tiff;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReader;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import static com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry.getValueLength;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -46,7 +39,15 @@ import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import static com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry.getValueLength;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReader;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
/**
|
||||
* TIFFReader
|
||||
@@ -336,7 +337,8 @@ public final class TIFFReader extends MetadataReader {
|
||||
else {
|
||||
long valueOffset = readOffset(pInput); // This is the *value* iff the value size is <= offsetSize
|
||||
|
||||
if (length > 0 && length < valueOffset + valueLength) {
|
||||
// Note: This a precaution
|
||||
if (count >= Integer.MAX_VALUE || length > 0 && length < valueOffset + valueLength) {
|
||||
value = new EOFException(String.format("TIFF value offset or size too large: %d/%d bytes (length: %d bytes)", valueOffset, valueLength, length));
|
||||
}
|
||||
else {
|
||||
@@ -367,7 +369,7 @@ public final class TIFFReader extends MetadataReader {
|
||||
long pos = pInput.getStreamPosition();
|
||||
try {
|
||||
pInput.seek(pOffset);
|
||||
return readValue(pInput, pType, pCount);
|
||||
return readValue(pInput, pType, pCount, longOffsets);
|
||||
}
|
||||
catch (EOFException e) {
|
||||
// TODO: Add warning listener API and report problem to client code
|
||||
@@ -379,10 +381,10 @@ public final class TIFFReader extends MetadataReader {
|
||||
}
|
||||
|
||||
private Object readValueInLine(final ImageInputStream pInput, final short pType, final int pCount) throws IOException {
|
||||
return readValue(pInput, pType, pCount);
|
||||
return readValue(pInput, pType, pCount, longOffsets);
|
||||
}
|
||||
|
||||
private static Object readValue(final ImageInputStream pInput, final short pType, final int pCount) throws IOException {
|
||||
private static Object readValue(final ImageInputStream pInput, final short pType, final int pCount, boolean bigTIFF) throws IOException {
|
||||
// TODO: Review value "widening" for the unsigned types. Right now it's inconsistent. Should we leave it to client code?
|
||||
// TODO: New strategy: Leave data as is, instead perform the widening in TIFFEntry.getValue.
|
||||
// TODO: Add getValueByte/getValueUnsignedByte/getValueShort/getValueUnsignedShort/getValueInt/etc... in API.
|
||||
@@ -513,24 +515,24 @@ public final class TIFFReader extends MetadataReader {
|
||||
case TIFF.TYPE_LONG8:
|
||||
case TIFF.TYPE_SLONG8:
|
||||
case TIFF.TYPE_IFD8:
|
||||
// TODO: Assert BigTiff (version == 43)
|
||||
if (bigTIFF) {
|
||||
if (pCount == 1) {
|
||||
long val = pInput.readLong();
|
||||
if (pType != TIFF.TYPE_SLONG8 && val < 0) {
|
||||
throw new IIOException(String.format("Value > %s", Long.MAX_VALUE));
|
||||
}
|
||||
|
||||
if (pCount == 1) {
|
||||
long val = pInput.readLong();
|
||||
if (pType != TIFF.TYPE_SLONG8 && val < 0) {
|
||||
throw new IIOException(String.format("Value > %s", Long.MAX_VALUE));
|
||||
return val;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
long[] longs = new long[pCount];
|
||||
for (int i = 0; i < pCount; i++) {
|
||||
longs[i] = pInput.readLong();
|
||||
}
|
||||
|
||||
long[] longs = new long[pCount];
|
||||
for (int i = 0; i < pCount; i++) {
|
||||
longs[i] = pInput.readLong();
|
||||
return longs;
|
||||
}
|
||||
|
||||
return longs;
|
||||
|
||||
default:
|
||||
// Spec says skip unknown values
|
||||
return new Unknown(pType, pCount, pos);
|
||||
|
||||
+3
-2
@@ -31,10 +31,11 @@
|
||||
package com.twelvemonkeys.imageio.metadata;
|
||||
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.matchers.TypeSafeMatcher;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
@@ -58,7 +59,7 @@ public abstract class MetadataReaderAbstractTest {
|
||||
ImageIO.setUseCache(false);
|
||||
}
|
||||
|
||||
protected final URL getResource(final String name) throws IOException {
|
||||
protected final URL getResource(final String name) {
|
||||
return getClass().getResource(name);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -35,6 +35,7 @@ import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
|
||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -44,6 +45,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
|
||||
+2
-1
@@ -32,14 +32,15 @@ package com.twelvemonkeys.imageio.metadata.iptc;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* IPTCReaderTest
|
||||
|
||||
+29
-10
@@ -30,6 +30,20 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.metadata.tiff;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
@@ -37,16 +51,6 @@ import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
import com.twelvemonkeys.imageio.metadata.exif.EXIF;
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* TIFFReaderTest
|
||||
@@ -346,6 +350,21 @@ public class TIFFReaderTest extends MetadataReaderAbstractTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithoutOOME() throws IOException {
|
||||
// This EXIF segment from a JPEG contains an Interop IFD, containing a weird value that could be interpreted
|
||||
// as a huge SLONG8 field (valid for BigTIFF only).
|
||||
// OutOfMemoryError would only happen if length of stream is not known (ie. reading from underlying stream).
|
||||
try (InputStream stream = getResource("/exif/exif-bad-interop-oome.bin").openStream()) {
|
||||
CompoundDirectory directory = (CompoundDirectory) createReader().read(new MemoryCacheImageInputStream(stream));
|
||||
assertEquals(2, directory.directoryCount());
|
||||
assertEquals(11, directory.getDirectory(0).size());
|
||||
assertEquals(6, directory.getDirectory(1).size());
|
||||
assertEquals("Picasa", directory.getDirectory(0).getEntryById(TIFF.TAG_SOFTWARE).getValue());
|
||||
assertEquals("2020:11:17 16:05:37", directory.getDirectory(0).getEntryById(TIFF.TAG_DATE_TIME).getValueAsString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 200)
|
||||
public void testReadCyclicExifWithoutLoopOrOOME() throws IOException {
|
||||
// This EXIF segment has an interesting bug...
|
||||
|
||||
+15
-1
@@ -34,6 +34,7 @@ import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
|
||||
import com.twelvemonkeys.imageio.metadata.Directory;
|
||||
import com.twelvemonkeys.imageio.metadata.Entry;
|
||||
import com.twelvemonkeys.imageio.metadata.MetadataReaderAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -46,7 +47,9 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* XMPReaderTest
|
||||
@@ -377,6 +380,7 @@ public class XMPReaderTest extends MetadataReaderAbstractTest {
|
||||
// photoshop|http://ns.adobe.com/photoshop/1.0/
|
||||
Directory photoshop = getDirectoryByNS(compound, XMP.NS_PHOTOSHOP);
|
||||
|
||||
assertNotNull(photoshop);
|
||||
assertEquals(3, photoshop.size());
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/ColorMode"), hasValue("1"));
|
||||
assertThat(photoshop.getEntryById("http://ns.adobe.com/photoshop/1.0/ICCProfile"), hasValue("Dot Gain 20%"));
|
||||
@@ -392,6 +396,8 @@ public class XMPReaderTest extends MetadataReaderAbstractTest {
|
||||
|
||||
// xapMM|http://ns.adobe.com/xap/1.0/mm/
|
||||
Directory mm = getDirectoryByNS(compound, XMP.NS_XAP_MM);
|
||||
|
||||
assertNotNull(mm);
|
||||
assertEquals(3, mm.size());
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/DocumentID"), hasValue("uuid:6DCA50CC7D53DD119F20F5A7EA4C9BEC"));
|
||||
assertThat(directory.getEntryById("http://ns.adobe.com/xap/1.0/mm/InstanceID"), hasValue("uuid:6ECA50CC7D53DD119F20F5A7EA4C9BEC"));
|
||||
@@ -416,6 +422,8 @@ public class XMPReaderTest extends MetadataReaderAbstractTest {
|
||||
|
||||
// dc|http://purl.org/dc/elements/1.1/
|
||||
Directory dc = getDirectoryByNS(compound, XMP.NS_DC);
|
||||
|
||||
assertNotNull(dc);
|
||||
assertEquals(1, dc.size());
|
||||
|
||||
assertThat(dc.getEntryById("http://purl.org/dc/elements/1.1/format"), hasValue("image/jpeg"));
|
||||
@@ -430,6 +438,8 @@ public class XMPReaderTest extends MetadataReaderAbstractTest {
|
||||
|
||||
// tiff|http://ns.adobe.com/tiff/1.0/
|
||||
Directory tiff = getDirectoryByNS(compound, XMP.NS_TIFF);
|
||||
|
||||
assertNotNull(tiff);
|
||||
assertEquals(5, tiff.size());
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/Orientation"), hasValue("1"));
|
||||
assertThat(tiff.getEntryById("http://ns.adobe.com/tiff/1.0/XResolution"), hasValue("720000/10000"));
|
||||
@@ -447,6 +457,8 @@ public class XMPReaderTest extends MetadataReaderAbstractTest {
|
||||
|
||||
// xap|http://ns.adobe.com/xap/1.0/
|
||||
Directory xap = getDirectoryByNS(compound, XMP.NS_XAP);
|
||||
|
||||
assertNotNull(xap);
|
||||
assertEquals(4, xap.size());
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/ModifyDate"), hasValue("2008-07-16T14:44:49-07:00"));
|
||||
assertThat(xap.getEntryById("http://ns.adobe.com/xap/1.0/CreatorTool"), hasValue("Adobe Photoshop CS3 Windows"));
|
||||
@@ -463,6 +475,8 @@ public class XMPReaderTest extends MetadataReaderAbstractTest {
|
||||
|
||||
// exif|http://ns.adobe.com/exif/1.0/
|
||||
Directory exif = getDirectoryByNS(compound, XMP.NS_EXIF);
|
||||
|
||||
assertNotNull(exif);
|
||||
assertEquals(4, exif.size());
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/ColorSpace"), hasValue("-1")); // SIC. Same as unsigned short 65535, meaning "uncalibrated"?
|
||||
assertThat(exif.getEntryById("http://ns.adobe.com/exif/1.0/PixelXDimension"), hasValue("426"));
|
||||
|
||||
Binary file not shown.
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-pcx</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: PCX plugin</name>
|
||||
@@ -21,6 +21,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+5
-13
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.dcx;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -54,12 +55,6 @@ import static org.junit.Assert.assertNotNull;
|
||||
* @version $Id: DCXImageReaderTest.java,v 1.0 03.07.14 22:28 haraldk Exp$
|
||||
*/
|
||||
public class DCXImageReaderTest extends ImageReaderAbstractTest<DCXImageReader> {
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Collections.singletonList(
|
||||
new TestData(getClassLoaderResource("/dcx/input.dcx"), new Dimension(70, 46)) // RLE encoded RGB (the only sample I've found)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
@@ -67,13 +62,10 @@ public class DCXImageReaderTest extends ImageReaderAbstractTest<DCXImageReader>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<DCXImageReader> getReaderClass() {
|
||||
return DCXImageReader.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DCXImageReader createReader() {
|
||||
return new DCXImageReader(createProvider());
|
||||
protected List<TestData> getTestData() {
|
||||
return Collections.singletonList(
|
||||
new TestData(getClassLoaderResource("/dcx/input.dcx"), new Dimension(70, 46)) // RLE encoded RGB (the only sample I've found)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-15
@@ -31,6 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.pcx;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -55,6 +56,11 @@ import static org.junit.Assert.assertNotNull;
|
||||
* @version $Id: PCXImageReaderTest.java,v 1.0 03.07.14 22:28 haraldk Exp$
|
||||
*/
|
||||
public class PCXImageReaderTest extends ImageReaderAbstractTest<PCXImageReader> {
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new PCXImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestData> getTestData() {
|
||||
return Arrays.asList(
|
||||
@@ -79,21 +85,6 @@ public class PCXImageReaderTest extends ImageReaderAbstractTest<PCXImageReader>
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new PCXImageReaderSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<PCXImageReader> getReaderClass() {
|
||||
return PCXImageReader.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PCXImageReader createReader() {
|
||||
return new PCXImageReader(createProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getFormatNames() {
|
||||
return Arrays.asList("PCX", "pcx");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-pdf</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: PDF plugin</name>
|
||||
@@ -22,6 +22,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-pict</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: PICT plugin</name>
|
||||
@@ -19,6 +19,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
+64
-8
@@ -60,6 +60,13 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase {
|
||||
}
|
||||
|
||||
ImageInputStream stream = (ImageInputStream) pSource;
|
||||
|
||||
// PICT format don't have good magic and our method often gives false positives,
|
||||
// We'll check for other known formats (BMP, GIF, JPEG, PNG, PSD, TIFF) first
|
||||
if (isOtherFormat(stream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stream.mark();
|
||||
|
||||
try {
|
||||
@@ -68,13 +75,12 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// Skip header 512 bytes for file-based streams
|
||||
stream.reset();
|
||||
|
||||
// We need to set mark again, to make sure the reset call in
|
||||
// We need to reset AND set mark again, to make sure the reset call in
|
||||
// the finally block will not consume existing marks
|
||||
stream.reset();
|
||||
stream.mark();
|
||||
|
||||
// Skip header 512 bytes for file-based streams
|
||||
skipNullHeader(stream);
|
||||
}
|
||||
|
||||
@@ -88,6 +94,60 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Candidate util method.
|
||||
// Might need to be able to exclude some formats
|
||||
// Might need to return the format matched...
|
||||
static boolean isOtherFormat(final ImageInputStream stream) throws IOException {
|
||||
stream.mark();
|
||||
|
||||
try {
|
||||
byte[] signature = new byte[8];
|
||||
stream.readFully(signature);
|
||||
|
||||
// BMP: off: 0, len: 2, magic: 'B', 'M'
|
||||
// GIF: off: 0, len: 6, magic: 'G', 'I', 'F', '8', ('7' | '9'), 'a' (use only "GIF8"?)
|
||||
// JPEG: off 0, len: 2, magic: 0xffd8 (SOI marker)
|
||||
// PNG: off: 0, len: 8, magic: 0x89, 'P', 'N', 'G', 0x0d0a1a0a
|
||||
// PSD: off: 0, len: 4, magic: '8', 'B', 'P', 'S'
|
||||
// TIFF: off: 0, len: 4, magic: ('I', 'I', 0x00, (0x42 | 0x43)) | ('M', 'M', (0x42 | 0x43), 0x00) (43 is bigTiff)
|
||||
if (signature[0] == 'B' && signature[1] == 'M') {
|
||||
// BMP
|
||||
return true;
|
||||
}
|
||||
if (signature[0] == 'G' && signature[1] == 'I' && signature[2] == 'F' && signature[3] == '8'
|
||||
&& (signature[4] == '7' || signature[4] == '9') && signature[5] == 'a') {
|
||||
// GIF
|
||||
return true;
|
||||
}
|
||||
if (signature[0] == (byte) 0xFF && signature[1] == (byte) 0xD8 && signature[2] == (byte) 0xFF) {
|
||||
// JPEG
|
||||
return true;
|
||||
}
|
||||
if (signature[0] == (byte) 0x89 && signature[1] == 'P' && signature[2] == 'N' && signature[3] == 'G'
|
||||
&& signature[4] == 0x0D && signature[5] == 0x0A && signature[6] == 0x1A && signature[7] == 0x0A) {
|
||||
// PNG
|
||||
return true;
|
||||
}
|
||||
if (signature[0] == '8' && signature[1] == 'B' && signature[2] == 'P' && signature[3] == 'S') {
|
||||
// PSD
|
||||
return true;
|
||||
}
|
||||
if ((signature[0] == 'I' && signature[1] == 'I' && (signature[2] == 42 || signature[2] == 43) && signature[3] == 0x00)
|
||||
|| signature[0] == 'M' && signature[1] == 'M' && signature[2] == 0x00 && (signature[3] == 42 || signature[3] == 43)) {
|
||||
// TIFF/BigTIFF
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (EOFException ignore) {
|
||||
// Can't be any of the formats
|
||||
}
|
||||
finally {
|
||||
stream.reset();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void skipNullHeader(final ImageInputStream pStream) throws IOException {
|
||||
// NOTE: Only skip if FILE FORMAT, not needed for Mac OS DnD
|
||||
// Spec says "platform dependent", may not be all nulls..
|
||||
@@ -102,10 +162,6 @@ public final class PICTImageReaderSpi extends ImageReaderSpiBase {
|
||||
// Sanity check bounding box
|
||||
int y1 = pStream.readUnsignedShort();
|
||||
int x1 = pStream.readUnsignedShort();
|
||||
// TODO: Figure out if frame can ever start at negative bounds...
|
||||
// if (x1 != 0 || y1 != 0) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
int y2 = pStream.readUnsignedShort();
|
||||
int x2 = pStream.readUnsignedShort();
|
||||
|
||||
+52
-22
@@ -33,6 +33,7 @@ package com.twelvemonkeys.imageio.plugins.pict;
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStreamSpi;
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -46,8 +47,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static com.twelvemonkeys.imageio.plugins.pict.PICTImageReaderSpi.isOtherFormat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* ICOImageReaderTestCase
|
||||
@@ -62,7 +63,10 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest<PICTImageReader
|
||||
IIORegistry.getDefaultInstance().registerServiceProvider(new ByteArrayImageInputStreamSpi());
|
||||
}
|
||||
|
||||
static ImageReaderSpi sProvider = new PICTImageReaderSpi();
|
||||
@Override
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return new PICTImageReaderSpi();
|
||||
}
|
||||
|
||||
// TODO: Should also test the clipboard format (without 512 byte header)
|
||||
protected List<TestData> getTestData() {
|
||||
@@ -91,31 +95,53 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest<PICTImageReader
|
||||
);
|
||||
}
|
||||
|
||||
protected ImageReaderSpi createProvider() {
|
||||
return sProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PICTImageReader createReader() {
|
||||
return new PICTImageReader(sProvider);
|
||||
}
|
||||
|
||||
protected Class<PICTImageReader> getReaderClass() {
|
||||
return PICTImageReader.class;
|
||||
}
|
||||
|
||||
protected List<String> getFormatNames() {
|
||||
return Collections.singletonList("pict");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSuffixes() {
|
||||
return Arrays.asList("pct", "pict");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getMIMETypes() {
|
||||
return Arrays.asList("image/pict", "image/x-pict");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsOtherFormat() throws IOException {
|
||||
assertFalse(isOtherFormat(new ByteArrayImageInputStream(new byte[8])));
|
||||
|
||||
// BMP
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'B', 'M', 0, 0, 0, 0, 0, 0})));
|
||||
|
||||
// GIF
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'G', 'I', 'F', '8', '7', 'a', 0, 0})));
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'G', 'I', 'F', '8', '9', 'a', 0, 0})));
|
||||
|
||||
// JPEG (JFIF, EXIF, "raw")
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE0, 0, 0, 0, 0})));
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE1, 0, 0, 0, 0})));
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xDB, 0, 0, 0, 0})));
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xC4, 0, 0, 0, 0})));
|
||||
|
||||
// PNG
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {(byte) 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A})));
|
||||
|
||||
// PSD
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'8', 'B', 'P', 'S', 0, 0, 0, 0})));
|
||||
|
||||
// TIFF (Little Endian, Big Endian)
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'I', 'I', 42, 0, 0, 0, 0, 0})));
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'M', 'M', 0, 42, 0, 0, 0, 0})));
|
||||
|
||||
// BigTIFF (Little Endian, Big Endian)
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'I', 'I', 43, 0, 0, 0, 0, 0})));
|
||||
assertTrue(isOtherFormat(new ByteArrayImageInputStream(new byte[] {'M', 'M', 0, 43, 0, 0, 0, 0})));
|
||||
}
|
||||
|
||||
@Ignore("Known issue")
|
||||
@Test
|
||||
@Override
|
||||
@@ -130,7 +156,7 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest<PICTImageReader
|
||||
stream.mark();
|
||||
stream.seek(123);
|
||||
|
||||
sProvider.canDecodeInput(stream);
|
||||
((ImageReaderSpi) new PICTImageReaderSpi()).canDecodeInput(stream);
|
||||
|
||||
assertEquals(123, stream.getStreamPosition());
|
||||
stream.reset();
|
||||
@@ -144,35 +170,39 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest<PICTImageReader
|
||||
public void testProviderNotMatchJPEG() throws IOException {
|
||||
// This JPEG contains PICT magic bytes at locations a PICT would normally have them.
|
||||
// We should not claim to be able read it.
|
||||
assertFalse(sProvider.canDecodeInput(
|
||||
assertFalse(((ImageReaderSpi) new PICTImageReaderSpi()).canDecodeInput(
|
||||
new TestData(getClassLoaderResource("/jpeg/R-7439-1151526181.jpeg"),
|
||||
new Dimension(386, 396)
|
||||
)));
|
||||
assertFalse(((ImageReaderSpi) new PICTImageReaderSpi()).canDecodeInput(
|
||||
new TestData(getClassLoaderResource("/jpeg/89497426-adc19a00-d7ff-11ea-8ad1-0cbcd727b62a.jpeg"),
|
||||
new Dimension(640, 480)
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataExtV2() throws IOException, InterruptedException {
|
||||
public void testDataExtV2() throws IOException {
|
||||
PICTImageReader reader = createReader();
|
||||
reader.setInput(new ByteArrayImageInputStream(DATA_EXT_V2));
|
||||
reader.read(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataV2() throws IOException, InterruptedException {
|
||||
public void testDataV2() throws IOException {
|
||||
PICTImageReader reader = createReader();
|
||||
reader.setInput(new ByteArrayImageInputStream(DATA_V2));
|
||||
reader.read(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataV1() throws IOException, InterruptedException {
|
||||
public void testDataV1() throws IOException {
|
||||
PICTImageReader reader = createReader();
|
||||
reader.setInput(new ByteArrayImageInputStream(DATA_V1));
|
||||
reader.read(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataV1OvalRect() throws IOException, InterruptedException {
|
||||
public void testDataV1OvalRect() throws IOException {
|
||||
PICTImageReader reader = createReader();
|
||||
reader.setInput(new ByteArrayImageInputStream(DATA_V1_OVAL_RECT));
|
||||
reader.read(0);
|
||||
@@ -193,7 +223,7 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest<PICTImageReader
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataV1CopyBits() throws IOException, InterruptedException {
|
||||
public void testDataV1CopyBits() throws IOException {
|
||||
PICTImageReader reader = createReader();
|
||||
reader.setInput(new ByteArrayImageInputStream(DATA_V1_COPY_BITS));
|
||||
reader.read(0);
|
||||
|
||||
+6
-6
@@ -32,10 +32,12 @@ package com.twelvemonkeys.imageio.plugins.pict;
|
||||
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.awt.color.ColorSpace;
|
||||
@@ -55,12 +57,10 @@ import static org.junit.Assert.*;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: PICTImageWriterTest.java,v 1.0 20.01.12 12:26 haraldk Exp$
|
||||
*/
|
||||
public class PICTImageWriterTest extends ImageWriterAbstractTest {
|
||||
private final PICTImageWriterSpi provider = new PICTImageWriterSpi();
|
||||
|
||||
public class PICTImageWriterTest extends ImageWriterAbstractTest<PICTImageWriter> {
|
||||
@Override
|
||||
protected ImageWriter createImageWriter() {
|
||||
return new PICTImageWriter(provider);
|
||||
protected ImageWriterSpi createProvider() {
|
||||
return new PICTImageWriterSpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +79,7 @@ public class PICTImageWriterTest extends ImageWriterAbstractTest {
|
||||
|
||||
@Test
|
||||
public void testWriteReadCompare() throws IOException {
|
||||
ImageWriter writer = createImageWriter();
|
||||
ImageWriter writer = createWriter();
|
||||
|
||||
List<? extends RenderedImage> testData = getTestData();
|
||||
for (int i = 0; i < testData.size(); i++) {
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.6.2</version>
|
||||
</parent>
|
||||
<artifactId>imageio-pnm</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: PNM plugin</name>
|
||||
@@ -22,6 +22,7 @@
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-core</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+16
-11
@@ -30,6 +30,8 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pnm;
|
||||
|
||||
import com.twelvemonkeys.imageio.ImageWriterBase;
|
||||
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
@@ -40,27 +42,30 @@ import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
abstract class HeaderWriter {
|
||||
protected static final Charset UTF8 = Charset.forName("UTF8");
|
||||
protected final ImageOutputStream imageOutput;
|
||||
|
||||
protected HeaderWriter(final ImageOutputStream imageOutput) {
|
||||
this.imageOutput = imageOutput;
|
||||
}
|
||||
|
||||
public static void write(final IIOImage image, final ImageWriterSpi provider, final ImageOutputStream imageOutput) throws IOException {
|
||||
// TODO: This is somewhat sketchy...
|
||||
if (provider.getFormatNames()[0].equals("pam")) {
|
||||
new PAMHeaderWriter(imageOutput).writeHeader(image, provider);
|
||||
public static void write(final IIOImage image, final ImageWriterBase writer, final ImageOutputStream imageOutput) throws IOException {
|
||||
createHeaderWriter(writer.getFormatName(), imageOutput).writeHeader(image, writer.getOriginatingProvider());
|
||||
}
|
||||
|
||||
private static HeaderWriter createHeaderWriter(final String formatName, final ImageOutputStream imageOutput) {
|
||||
if (formatName.equals("pam")) {
|
||||
return new PAMHeaderWriter(imageOutput);
|
||||
}
|
||||
else if (provider.getFormatNames()[0].equals("pnm")) {
|
||||
new PNMHeaderWriter(imageOutput).writeHeader(image, provider);
|
||||
else if (formatName.equals("pnm")) {
|
||||
return new PNMHeaderWriter(imageOutput);
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unsupported provider: " + provider);
|
||||
throw new AssertionError("Unsupported format: " + formatName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +106,7 @@ abstract class HeaderWriter {
|
||||
|
||||
protected final void writeComments(final IIOMetadata metadata, final ImageWriterSpi provider) throws IOException {
|
||||
// TODO: Only write creator if not already present
|
||||
imageOutput.write(String.format("# CREATOR: %s %s\n", provider.getVendorName(), provider.getDescription(Locale.getDefault())).getBytes(UTF8));
|
||||
imageOutput.write(String.format("# CREATOR: %s %s\n", provider.getVendorName(), provider.getDescription(Locale.getDefault())).getBytes(UTF_8));
|
||||
|
||||
// Comments from metadata
|
||||
if (metadata != null && metadata.isStandardMetadataFormatSupported()) {
|
||||
@@ -111,7 +116,7 @@ abstract class HeaderWriter {
|
||||
for (int i = 0; i < textEntries.getLength(); i++) {
|
||||
// TODO: Write on the format "# KEYWORD: value" (if keyword != comment)?
|
||||
IIOMetadataNode textEntry = (IIOMetadataNode) textEntries.item(i);
|
||||
imageOutput.write(String.format("# %s", textEntry.getAttribute("value")).getBytes(UTF8));
|
||||
imageOutput.write(String.format("# %s", textEntry.getAttribute("value")).getBytes(UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ final class PAMHeaderParser extends HeaderParser {
|
||||
int depth = -1;
|
||||
int maxVal = -1;
|
||||
TupleType tupleType = null;
|
||||
List<String> comments = new ArrayList<String>();
|
||||
List<String> comments = new ArrayList<>();
|
||||
|
||||
String line;
|
||||
while ((line = input.readLine()) != null && !line.startsWith(ENDHDR)) {
|
||||
|
||||
+6
-4
@@ -35,6 +35,8 @@ import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
final class PAMHeaderWriter extends HeaderWriter {
|
||||
public PAMHeaderWriter(final ImageOutputStream imageOutput) {
|
||||
super(imageOutput);
|
||||
@@ -48,14 +50,14 @@ final class PAMHeaderWriter extends HeaderWriter {
|
||||
// Comments
|
||||
writeComments(image.getMetadata(), provider);
|
||||
// Write width/height and number of channels
|
||||
imageOutput.write(String.format("WIDTH %s\nHEIGHT %s\n", getWidth(image), getHeight(image)).getBytes(UTF8));
|
||||
imageOutput.write(String.format("DEPTH %s\n", getNumBands(image)).getBytes(UTF8));
|
||||
imageOutput.write(String.format("WIDTH %s\nHEIGHT %s\n", getWidth(image), getHeight(image)).getBytes(UTF_8));
|
||||
imageOutput.write(String.format("DEPTH %s\n", getNumBands(image)).getBytes(UTF_8));
|
||||
|
||||
// TODO: maxSample (8 or16 bit)
|
||||
imageOutput.write(String.format("MAXVAL %s\n", getMaxVal(image)).getBytes(UTF8));
|
||||
imageOutput.write(String.format("MAXVAL %s\n", getMaxVal(image)).getBytes(UTF_8));
|
||||
|
||||
// TODO: Determine tuple type based on input color model and image data
|
||||
TupleType tupleType = getNumBands(image) > 3 ? TupleType.RGB_ALPHA : TupleType.RGB;
|
||||
imageOutput.write(String.format("TUPLTYPE %s\nENDHDR\n", tupleType).getBytes(UTF8));
|
||||
imageOutput.write(String.format("TUPLTYPE %s\nENDHDR\n", tupleType).getBytes(UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pnm;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase;
|
||||
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class PAMImageReaderSpi extends ImageReaderSpiBase {
|
||||
|
||||
/**
|
||||
* Creates a {@code PAMImageReaderSpi}.
|
||||
*/
|
||||
public PAMImageReaderSpi() {
|
||||
super(new PAMProviderInfo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDecodeInput(final Object source) throws IOException {
|
||||
if (!(source instanceof ImageInputStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageInputStream stream = (ImageInputStream) source;
|
||||
stream.mark();
|
||||
|
||||
try {
|
||||
return stream.readShort() == PNM.PAM && stream.readInt() != PNM.XV_THUMBNAIL_MAGIC;
|
||||
}
|
||||
finally {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageReader createReaderInstance(final Object extension) {
|
||||
return new PNMImageReader(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(final Locale locale) {
|
||||
return "NetPBM Portable Arbitrary Map (PAM) image reader";
|
||||
}
|
||||
}
|
||||
+3
-23
@@ -30,39 +30,19 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pnm;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ProviderInfo;
|
||||
import com.twelvemonkeys.imageio.spi.ImageWriterSpiBase;
|
||||
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class PAMImageWriterSpi extends ImageWriterSpi {
|
||||
public final class PAMImageWriterSpi extends ImageWriterSpiBase {
|
||||
|
||||
/**
|
||||
* Creates a {@code PAMImageWriterSpi}.
|
||||
*/
|
||||
public PAMImageWriterSpi() {
|
||||
this(new PNMProviderInfo());
|
||||
}
|
||||
|
||||
private PAMImageWriterSpi(final ProviderInfo pProviderInfo) {
|
||||
super(
|
||||
pProviderInfo.getVendorName(),
|
||||
pProviderInfo.getVersion(),
|
||||
new String[] {"pam", "PAM"},
|
||||
new String[] {"pam"},
|
||||
new String[] {
|
||||
// No official IANA record exists, these are conventional
|
||||
"image/x-portable-arbitrarymap" // PAM
|
||||
},
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriter",
|
||||
new Class[] {ImageOutputStream.class},
|
||||
new String[] {"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi"},
|
||||
true, null, null, null, null,
|
||||
true, null, null, null, null
|
||||
);
|
||||
super(new PAMProviderInfo());
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(final ImageTypeSpecifier pType) {
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pnm;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo;
|
||||
|
||||
/**
|
||||
* PAMProviderInfo.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: harald.kuhr$
|
||||
* @version $Id: PAMProviderInfo.java,v 1.0 20/03/15 harald.kuhr Exp$
|
||||
*/
|
||||
class PAMProviderInfo extends ReaderWriterProviderInfo {
|
||||
public PAMProviderInfo() {
|
||||
super(PAMProviderInfo.class,
|
||||
new String[] {
|
||||
"pam",
|
||||
"PAM"
|
||||
},
|
||||
new String[] {"pam"},
|
||||
new String[] {
|
||||
// No official IANA record exists, these are conventional
|
||||
"image/x-portable-arbitrarymap"
|
||||
},
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReader",
|
||||
new String[] {
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageReaderSpi",
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi"
|
||||
},
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriter",
|
||||
new String[] {
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageWriterSpi",
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriterSpi"
|
||||
},
|
||||
true, // supports standard stream metadata
|
||||
null, null, // native stream format name and class
|
||||
null, null, // extra stream formats
|
||||
true, // supports standard image metadata
|
||||
null, null,
|
||||
null, null // extra image metadata formats
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -71,7 +71,7 @@ final class PFMHeaderParser extends HeaderParser {
|
||||
int height = 0;
|
||||
float maxSample = tupleType == TupleType.BLACKANDWHITE_WHITE_IS_ZERO ? 1 : 0; // PBM has no maxSample line
|
||||
|
||||
List<String> comments = new ArrayList<String>();
|
||||
List<String> comments = new ArrayList<>();
|
||||
|
||||
while (width == 0 || height == 0 || maxSample == 0) {
|
||||
String line = input.readLine();
|
||||
|
||||
+8
-11
@@ -45,6 +45,7 @@ final class PNMHeader {
|
||||
private final TupleType tupleType;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final float maxSampleFloat;
|
||||
private final int maxSample;
|
||||
|
||||
private final List<String> comments;
|
||||
@@ -57,8 +58,9 @@ final class PNMHeader {
|
||||
this.height = isTrue(height > 0, height, "height must be greater than: %d");
|
||||
isTrue(depth == tupleType.getSamplesPerPixel(), depth, String.format("incorrect depth for %s, expected %d: %d", tupleType, tupleType.getSamplesPerPixel(), depth));
|
||||
this.maxSample = isTrue(tupleType.isValidMaxSample(maxSample), maxSample, "maxSample out of range: %d");
|
||||
this.maxSampleFloat = this.maxSample;
|
||||
|
||||
this.comments = Collections.unmodifiableList(new ArrayList<String>(comments));
|
||||
this.comments = Collections.unmodifiableList(new ArrayList<>(comments));
|
||||
|
||||
byteOrder = ByteOrder.BIG_ENDIAN;
|
||||
}
|
||||
@@ -70,10 +72,11 @@ final class PNMHeader {
|
||||
this.height = isTrue(height > 0, height, "height must be greater than: %d");
|
||||
isTrue(depth == tupleType.getSamplesPerPixel(), depth, String.format("incorrect depth for %s, expected %d: %d", tupleType, tupleType.getSamplesPerPixel(), depth));
|
||||
|
||||
this.maxSample = -1;
|
||||
this.maxSample = 1;
|
||||
this.maxSampleFloat = maxSample;
|
||||
this.byteOrder = byteOrder;
|
||||
|
||||
this.comments = Collections.unmodifiableList(new ArrayList<String>(comments));
|
||||
this.comments = Collections.unmodifiableList(new ArrayList<>(comments));
|
||||
}
|
||||
|
||||
private boolean isValidFileType(final short fileType) {
|
||||
@@ -118,11 +121,8 @@ final class PNMHeader {
|
||||
if (maxSample <= PNM.MAX_VAL_16BIT) {
|
||||
return 16;
|
||||
}
|
||||
if ((maxSample & 0xffffffffL) <= PNM.MAX_VAL_32BIT) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
throw new AssertionError("maxSample exceeds 32 bit");
|
||||
return 32;
|
||||
}
|
||||
|
||||
public int getTransferType() {
|
||||
@@ -135,11 +135,8 @@ final class PNMHeader {
|
||||
if (maxSample <= PNM.MAX_VAL_16BIT) {
|
||||
return DataBuffer.TYPE_USHORT;
|
||||
}
|
||||
if ((maxSample & 0xffffffffL) <= PNM.MAX_VAL_32BIT) {
|
||||
return DataBuffer.TYPE_INT;
|
||||
}
|
||||
|
||||
throw new AssertionError("maxSample exceeds 32 bit");
|
||||
return DataBuffer.TYPE_INT;
|
||||
}
|
||||
|
||||
public List<String> getComments() {
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ final class PNMHeaderParser extends HeaderParser {
|
||||
int height = 0;
|
||||
int maxSample = tupleType == TupleType.BLACKANDWHITE_WHITE_IS_ZERO ? 1 : 0; // PBM has no maxSample line
|
||||
|
||||
List<String> comments = new ArrayList<String>();
|
||||
List<String> comments = new ArrayList<>();
|
||||
|
||||
while (width == 0 || height == 0 || maxSample == 0) {
|
||||
String line = input.readLine();
|
||||
|
||||
+4
-2
@@ -35,6 +35,8 @@ import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
final class PNMHeaderWriter extends HeaderWriter {
|
||||
public PNMHeaderWriter(final ImageOutputStream imageOutput) {
|
||||
super(imageOutput);
|
||||
@@ -52,11 +54,11 @@ final class PNMHeaderWriter extends HeaderWriter {
|
||||
writeComments(image.getMetadata(), provider);
|
||||
|
||||
// Dimensions (width/height)
|
||||
imageOutput.write(String.format("%s %s\n", getWidth(image), getHeight(image)).getBytes(HeaderWriter.UTF8));
|
||||
imageOutput.write(String.format("%s %s\n", getWidth(image), getHeight(image)).getBytes(UTF_8));
|
||||
|
||||
// MaxSample
|
||||
if (type != PNM.PBM) {
|
||||
imageOutput.write(String.format("%s\n", getMaxVal(image)).getBytes(HeaderWriter.UTF8));
|
||||
imageOutput.write(String.format("%s\n", getMaxVal(image)).getBytes(UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
-28
@@ -49,11 +49,13 @@ import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.twelvemonkeys.imageio.util.IIOUtil.subsampleRow;
|
||||
|
||||
public final class PNMImageReader extends ImageReaderBase {
|
||||
// TODO: Allow reading unknown tuple types as Raster!
|
||||
// TODO: readAsRenderedImage?
|
||||
@@ -83,7 +85,7 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
|
||||
static String asASCII(final short type) {
|
||||
byte[] asciiBytes = {(byte) ((type >> 8) & 0xff), (byte) (type & 0xff)};
|
||||
return new String(asciiBytes, Charset.forName("ASCII"));
|
||||
return new String(asciiBytes, StandardCharsets.US_ASCII);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,7 +152,6 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
|
||||
default:
|
||||
// TODO: Allow reading unknown tuple types as Raster!
|
||||
|
||||
throw new AssertionError("Unknown PNM tuple type: " + header.getTupleType());
|
||||
}
|
||||
}
|
||||
@@ -169,7 +170,7 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(final int imageIndex) throws IOException {
|
||||
ImageTypeSpecifier rawType = getRawImageType(imageIndex);
|
||||
|
||||
List<ImageTypeSpecifier> specifiers = new ArrayList<ImageTypeSpecifier>();
|
||||
List<ImageTypeSpecifier> specifiers = new ArrayList<>();
|
||||
|
||||
switch (header.getTupleType()) {
|
||||
case RGB:
|
||||
@@ -261,7 +262,7 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
for (int y = 0; y < height; y++) {
|
||||
switch (transferType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
readRowByte(destRaster, clippedRow, colorConvert, rowDataByte, samplesPerPixel, input, y, srcRegion, xSub, ySub);
|
||||
readRowByte(destRaster, clippedRow, colorConvert, rowDataByte, header.getBitsPerSample(), samplesPerPixel, input, y, srcRegion, xSub, ySub);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
readRowUShort(destRaster, clippedRow, rowDataUShort, samplesPerPixel, input, y, srcRegion, xSub, ySub);
|
||||
@@ -339,7 +340,7 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
Raster rowRaster,
|
||||
final ColorConvertOp colorConvert,
|
||||
final byte[] rowDataByte,
|
||||
final int samplesPerPixel,
|
||||
final int bitsPerSample, final int samplesPerPixel,
|
||||
final DataInput input, final int y,
|
||||
final Rectangle srcRegion,
|
||||
final int xSub, final int ySub) throws IOException {
|
||||
@@ -352,7 +353,9 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
input.readFully(rowDataByte);
|
||||
|
||||
// Subsample (horizontal)
|
||||
subsampleHorizontal(rowDataByte, rowDataByte.length, samplesPerPixel, xSub);
|
||||
if (xSub > 1) {
|
||||
subsampleRow(rowDataByte, srcRegion.x, srcRegion.width, rowDataByte, 0, samplesPerPixel, bitsPerSample, xSub);
|
||||
}
|
||||
|
||||
normalize(rowDataByte, 0, rowDataByte.length / xSub);
|
||||
|
||||
@@ -379,7 +382,9 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
readFully(input, rowDataUShort);
|
||||
|
||||
// Subsample (horizontal)
|
||||
subsampleHorizontal(rowDataUShort, rowDataUShort.length, samplesPerPixel, xSub);
|
||||
if (xSub > 1) {
|
||||
subsampleRow(rowDataUShort, srcRegion.x, srcRegion.width, rowDataUShort, 0, samplesPerPixel, 16, xSub);
|
||||
}
|
||||
|
||||
normalize(rowDataUShort);
|
||||
|
||||
@@ -402,11 +407,14 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
readFully(input, rowDataFloat);
|
||||
|
||||
// Subsample (horizontal)
|
||||
subsampleHorizontal(rowDataFloat, rowDataFloat.length, samplesPerPixel, xSub);
|
||||
if (xSub > 1) {
|
||||
subsampleRow(rowDataFloat, srcRegion.x, srcRegion.width, rowDataFloat, 0, samplesPerPixel, 32, xSub);
|
||||
}
|
||||
|
||||
normalize(rowDataFloat);
|
||||
|
||||
int destY = (y - srcRegion.y) / ySub;
|
||||
// Note: PFM is stored bottom to top!
|
||||
int destY = destRaster.getHeight() - 1 - (y - srcRegion.y) / ySub;
|
||||
// TODO: ColorConvertOp if needed
|
||||
destRaster.setDataElements(0, destY, rowRaster);
|
||||
}
|
||||
@@ -437,19 +445,6 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousSystemArraycopy")
|
||||
private void subsampleHorizontal(final Object data, final int length, final int samplesPerPixel, final int xSub) {
|
||||
if (xSub == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Super-special 1 bit subsampling handling for PBM
|
||||
|
||||
for (int x = 0; x < length / xSub; x += samplesPerPixel) {
|
||||
System.arraycopy(data, x * xSub, data, x, samplesPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
private void normalize(final byte[] rowData, final int start, final int length) {
|
||||
switch (header.getTupleType()) {
|
||||
case BLACKANDWHITE:
|
||||
@@ -484,13 +479,9 @@ public final class PNMImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private void normalize(final float[] rowData) {
|
||||
// TODO: Do the real thing, find min/max and normalize to range 0...255? But only if not reading raster..? Only support reading as raster?
|
||||
// Normalize
|
||||
for (int i = 0; i < rowData.length; i++) {
|
||||
// if (rowData[i] > 275f /*header.getMaxSampleFloat()*/) {
|
||||
// System.out.println("rowData[" + i + "]: " + rowData[i]);
|
||||
// }
|
||||
// rowData[i] = rowData[i] / 275f /*header.getMaxSampleFloat()*/;
|
||||
rowData[i] = Math.min(1, rowData[i]); // Clamp
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-38
@@ -30,51 +30,20 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pnm;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ProviderInfo;
|
||||
import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase;
|
||||
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class PNMImageReaderSpi extends ImageReaderSpi {
|
||||
public final class PNMImageReaderSpi extends ImageReaderSpiBase {
|
||||
|
||||
/**
|
||||
* Creates a {@code PNMImageReaderSpi}.
|
||||
*/
|
||||
public PNMImageReaderSpi() {
|
||||
this(new PNMProviderInfo());
|
||||
}
|
||||
|
||||
private PNMImageReaderSpi(final ProviderInfo providerInfo) {
|
||||
super(
|
||||
providerInfo.getVendorName(),
|
||||
providerInfo.getVersion(),
|
||||
new String[] {
|
||||
"pnm", "pbm", "pgm", "ppm", "pam", "pfm",
|
||||
"PNM", "PBM", "PGM", "PPM", "PAM", "PFM"
|
||||
},
|
||||
new String[] {"pbm", "pgm", "ppm", "pam", "pfm"},
|
||||
new String[] {
|
||||
// No official IANA record exists, these are conventional
|
||||
"image/x-portable-pixmap",
|
||||
"image/x-portable-anymap",
|
||||
"image/x-portable-arbitrarymap" // PAM
|
||||
},
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReader",
|
||||
new Class[] {ImageInputStream.class},
|
||||
new String[] {
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriterSpi",
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PAMImageWriterSpi"
|
||||
},
|
||||
true, // supports standard stream metadata
|
||||
null, null, // native stream format name and class
|
||||
null, null, // extra stream formats
|
||||
true, // supports standard image metadata
|
||||
null, null,
|
||||
null, null // extra image metadata formats
|
||||
);
|
||||
super(new PNMProviderInfo());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,8 +69,6 @@ public final class PNMImageReaderSpi extends ImageReaderSpi {
|
||||
case PNM.PFM_GRAY:
|
||||
case PNM.PFM_RGB:
|
||||
return true;
|
||||
case PNM.PAM:
|
||||
return stream.readInt() != PNM.XV_THUMBNAIL_MAGIC;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -112,12 +79,12 @@ public final class PNMImageReaderSpi extends ImageReaderSpi {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageReader createReaderInstance(final Object extension) throws IOException {
|
||||
public ImageReader createReaderInstance(final Object extension) {
|
||||
return new PNMImageReader(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(final Locale locale) {
|
||||
return "NetPBM Portable Any Map (PNM and PAM) image reader";
|
||||
return "NetPBM Portable Any Map (PNM) image reader";
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -65,10 +65,11 @@ public final class PNMImageWriter extends ImageWriterBase {
|
||||
|
||||
@Override
|
||||
public void write(final IIOMetadata streamMetadata, final IIOImage image, final ImageWriteParam param) throws IOException {
|
||||
assertOutput();
|
||||
// TODO: Issue warning if streamMetadata is non-null?
|
||||
// TODO: Issue warning if IIOImage contains thumbnails or other data we can't store?
|
||||
|
||||
HeaderWriter.write(image, getOriginatingProvider(), imageOutput);
|
||||
HeaderWriter.write(image, this, imageOutput);
|
||||
|
||||
// TODO: Sub region
|
||||
// TODO: Subsampling
|
||||
|
||||
+3
-27
@@ -30,15 +30,13 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pnm;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ProviderInfo;
|
||||
import com.twelvemonkeys.imageio.spi.ImageWriterSpiBase;
|
||||
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class PNMImageWriterSpi extends ImageWriterSpi {
|
||||
public final class PNMImageWriterSpi extends ImageWriterSpiBase {
|
||||
|
||||
// TODO: Consider one Spi for each sub-format, as it makes no sense for the writer to write PPM if client code requested PBM or PGM format.
|
||||
// ...Then again, what if user asks for PNM? :-P
|
||||
@@ -47,29 +45,7 @@ public final class PNMImageWriterSpi extends ImageWriterSpi {
|
||||
* Creates a {@code PNMImageWriterSpi}.
|
||||
*/
|
||||
public PNMImageWriterSpi() {
|
||||
this(new PNMProviderInfo());
|
||||
}
|
||||
|
||||
private PNMImageWriterSpi(final ProviderInfo pProviderInfo) {
|
||||
super(
|
||||
pProviderInfo.getVendorName(),
|
||||
pProviderInfo.getVersion(),
|
||||
new String[] {
|
||||
"pnm", "pbm", "pgm", "ppm",
|
||||
"PNM", "PBM", "PGM", "PPM"
|
||||
},
|
||||
new String[] {"pbm", "pgm", "ppm"},
|
||||
new String[] {
|
||||
// No official IANA record exists, these are conventional
|
||||
"image/x-portable-pixmap",
|
||||
"image/x-portable-anymap"
|
||||
},
|
||||
"com.twelvemonkeys.imageio.plugins.pnm.PNMImageWriter",
|
||||
new Class[] {ImageOutputStream.class},
|
||||
new String[] {"com.twelvemonkeys.imageio.plugins.pnm.PNMImageReaderSpi"},
|
||||
true, null, null, null, null,
|
||||
true, null, null, null, null
|
||||
);
|
||||
super(new PNMProviderInfo());
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(final ImageTypeSpecifier pType) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user