View Javadoc
1   /*
2    * SmartSprites Project
3    *
4    * Copyright (C) 2007-2009, Stanisław Osiński.
5    * All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without modification,
8    * are permitted provided that the following conditions are met:
9    *
10   * - Redistributions of  source code must  retain the above  copyright notice, this
11   *   list of conditions and the following disclaimer.
12   *
13   * - Redistributions in binary form must reproduce the above copyright notice, this
14   *   list of conditions and the following  disclaimer in  the documentation  and/or
15   *   other materials provided with the distribution.
16   *
17   * - Neither the name of the SmartSprites Project nor the names of its contributors
18   *   may  be used  to endorse  or  promote  products derived   from  this  software
19   *   without specific prior written permission.
20   *
21   * - We kindly request that you include in the end-user documentation provided with
22   *   the redistribution and/or in the software itself an acknowledgement equivalent
23   *   to  the  following: "This product includes software developed by the SmartSprites
24   *   Project."
25   *
26   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  AND
27   * ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED  TO, THE IMPLIED
28   * WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR  PURPOSE   ARE
29   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE  FOR
30   * ANY DIRECT, INDIRECT, INCIDENTAL,  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  DAMAGES
31   * (INCLUDING, BUT  NOT LIMITED  TO, PROCUREMENT  OF SUBSTITUTE  GOODS OR SERVICES;
32   * LOSS OF USE, DATA, OR PROFITS;  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND  ON
33   * ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT  LIABILITY,  OR TORT
34   * (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY  OUT OF THE USE  OF THIS
35   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36   */
37  package org.carrot2.util;
38  
39  import static org.junit.jupiter.api.Assertions.assertEquals;
40  import static org.junit.jupiter.api.Assertions.assertThrows;
41  
42  import java.awt.image.BufferedImage;
43  import java.io.IOException;
44  
45  import org.junit.jupiter.api.Test;
46  
47  import amd.Quantize;
48  
49  /**
50   * Test cases for {@link Quantize}.
51   */
52  class ColorQuantizerTest extends BufferedImageTestBase {
53  
54      /**
55       * Test one color.
56       *
57       * @throws IOException
58       *             Signals that an I/O exception has occurred.
59       */
60      @Test
61      void testOneColor() throws IOException {
62          final String fileName = "one-color.png";
63          final BufferedImage quantized = ColorQuantizer.quantize(image(fileName));
64          org.carrot2.labs.test.Assertions.assertThat(quantized).doesNotHaveAlpha().hasNumberOfColorsEqualTo(1)
65                  .isIndexedColor();
66      }
67  
68      /**
69       * Test no alpha.
70       *
71       * @throws IOException
72       *             Signals that an I/O exception has occurred.
73       */
74      @Test
75      void testNoAlpha() throws IOException {
76          final String fileName = "no-alpha.png";
77          final BufferedImage quantized = ColorQuantizer.quantize(image(fileName));
78          org.carrot2.labs.test.Assertions.assertThat(quantized).doesNotHaveAlpha().hasNumberOfColorsEqualTo(4)
79                  .isIndexedColor();
80      }
81  
82      /**
83       * Test bit alpha.
84       *
85       * @throws IOException
86       *             Signals that an I/O exception has occurred.
87       */
88      @Test
89      void testBitAlpha() throws IOException {
90          final String fileName = "bit-alpha.png";
91          final BufferedImage quantized = ColorQuantizer.quantize(image(fileName));
92          org.carrot2.labs.test.Assertions.assertThat(quantized).hasBitAlpha().hasNumberOfColorsEqualTo(1)
93                  .isIndexedColor();
94      }
95  
96      /**
97       * Test full alpha.
98       *
99       * @throws IOException
100      *             Signals that an I/O exception has occurred.
101      */
102     @Test
103     void testFullAlpha() throws IOException {
104         final String fileName = "full-alpha.png";
105         final BufferedImage quantized = ColorQuantizer.quantize(image(fileName));
106         org.carrot2.labs.test.Assertions.assertThat(quantized).hasBitAlpha().hasNumberOfColorsEqualTo(3)
107                 .isIndexedColor();
108     }
109 
110     /**
111      * Test exact colors quantize.
112      *
113      * @throws IOException
114      *             Signals that an I/O exception has occurred.
115      */
116     @Test
117     void testExactColorsQuantize() throws IOException {
118         final String fileName = "exact-colors.png";
119         final BufferedImage quantized = ColorQuantizer.quantize(image(fileName));
120         org.carrot2.labs.test.Assertions.assertThat(quantized).hasBitAlpha().hasNumberOfColorsEqualTo(16)
121                 .isIndexedColor();
122     }
123 
124     /**
125      * Test exact colors reduce.
126      *
127      * @throws IOException
128      *             Signals that an I/O exception has occurred.
129      */
130     @Test
131     void testExactColorsReduce() throws IOException {
132         final String fileName = "exact-colors.png";
133         final BufferedImage quantized = ColorQuantizer.reduce(image(fileName));
134         org.carrot2.labs.test.Assertions.assertThat(quantized).hasBitAlpha().hasNumberOfColorsEqualTo(255)
135                 .isIndexedColor();
136     }
137 
138     /**
139      * Test many colors quantize.
140      *
141      * @throws IOException
142      *             Signals that an I/O exception has occurred.
143      */
144     @Test
145     void testManyColorsQuantize() throws IOException {
146         final String fileName = "many-colors.png";
147         final BufferedImage quantized = ColorQuantizer.quantize(image(fileName));
148         org.carrot2.labs.test.Assertions.assertThat(quantized).doesNotHaveAlpha().hasNumberOfColorsEqualTo(61)
149                 .isIndexedColor();
150         // Current quantizer is far from perfect
151     }
152 
153     /**
154      * Test many colors reduce.
155      *
156      * @throws IOException
157      *             Signals that an I/O exception has occurred.
158      */
159     @Test
160     void testManyColorsReduce() throws IOException {
161         final String fileName = "many-colors.png";
162         assertThrows(IllegalArgumentException.class, () -> {
163             ColorQuantizer.reduce(image(fileName));
164         });
165     }
166 
167     /**
168      * Test can reduce without data loss.
169      *
170      * @throws IOException
171      *             Signals that an I/O exception has occurred.
172      */
173     @Test
174     void testCanReduceWithoutDataLoss() throws IOException {
175         checkDataLoss("bit-alpha.png", true);
176         checkDataLoss("exact-colors.png", true);
177         checkDataLoss("full-alpha.png", false);
178         checkDataLoss("many-colors.png", false);
179         checkDataLoss("no-alpha.png", true);
180         checkDataLoss("one-color.png", true);
181     }
182 
183     /**
184      * Check data loss.
185      *
186      * @param path
187      *            the path
188      * @param expectedCanReduce
189      *            the expected can reduce
190      *
191      * @throws IOException
192      *             Signals that an I/O exception has occurred.
193      */
194     private void checkDataLoss(String path, boolean expectedCanReduce) throws IOException {
195         assertEquals(expectedCanReduce,
196                 ColorQuantizer.getColorReductionInfo(image(path)).canReduceWithoutQualityLoss());
197     }
198 }