Restored a corrected Reed-Solomon optimization and fixed a small issue in black box...
[zxing.git] / core / test / src / com / google / zxing / common / AbstractBlackBoxTestCase.java
1 /*
2  * Copyright 2008 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.common;
18
19 import com.google.zxing.BarcodeFormat;
20 import com.google.zxing.DecodeHintType;
21 import com.google.zxing.MonochromeBitmapSource;
22 import com.google.zxing.Reader;
23 import com.google.zxing.ReaderException;
24 import com.google.zxing.Result;
25 import com.google.zxing.client.j2se.BufferedImageMonochromeBitmapSource;
26 import junit.framework.TestCase;
27
28 import javax.imageio.ImageIO;
29 import java.awt.image.BufferedImage;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FilenameFilter;
33 import java.io.IOException;
34 import java.io.InputStreamReader;
35 import java.net.URL;
36 import java.util.Hashtable;
37
38 /**
39  * @author srowen@google.com (Sean Owen)
40  */
41 public abstract class AbstractBlackBoxTestCase extends TestCase {
42
43   private static final Hashtable TRY_HARDER_HINT;
44   static {
45     TRY_HARDER_HINT = new Hashtable();
46     TRY_HARDER_HINT.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
47   }
48
49   private static final FilenameFilter IMAGE_NAME_FILTER = new FilenameFilter() {
50     public boolean accept(File dir, String name) {
51       String lowerCase = name.toLowerCase();
52       return
53           lowerCase.endsWith(".jpg") || lowerCase.endsWith(".jpeg") ||
54               lowerCase.endsWith(".gif") || lowerCase.endsWith(".png") ||
55               lowerCase.endsWith(".url");
56     }
57   };
58
59   private final File testBase;
60   private final Reader barcodeReader;
61   private final double passPercent;
62   private final BarcodeFormat expectedFormat;
63
64   protected AbstractBlackBoxTestCase(File testBase,
65                                      Reader barcodeReader,
66                                      double passPercent,
67                                      BarcodeFormat expectedFormat) {
68     this.testBase = testBase;
69     this.barcodeReader = barcodeReader;
70     this.passPercent = passPercent;
71     this.expectedFormat = expectedFormat;
72   }
73
74   public void testBlackBox() throws IOException {
75
76     assertTrue("Please run from the 'core' directory", testBase.exists());
77
78     File[] imageFiles = testBase.listFiles(IMAGE_NAME_FILTER);
79     int passedCount = 0;
80     for (File testImage : imageFiles) {
81       System.out.println("Starting " + testImage.getAbsolutePath());
82
83       BufferedImage image;
84       if (testImage.getName().endsWith(".url")) {
85         String urlString = readFileAsString(testImage);
86         image = ImageIO.read(new URL(urlString));
87       } else {
88         image = ImageIO.read(testImage);
89       }
90       MonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image);
91       Result result;
92       try {
93         result = barcodeReader.decode(source);
94       } catch (ReaderException re) {
95         System.out.println(re);
96         continue;
97       }
98
99       assertEquals(expectedFormat, result.getBarcodeFormat());
100
101       String testImageFileName = testImage.getName();
102       File expectedTextFile =
103           new File(testBase, testImageFileName.substring(0, testImageFileName.indexOf('.')) + ".txt");
104       String expectedText = readFileAsString(expectedTextFile);
105       String resultText = result.getText();
106
107       boolean passed = expectedText.equals(resultText);
108       if (passed) {
109         passedCount++;
110       } else {
111         fail("Mismatch: expected '" + expectedText + "' but got '" + resultText + '\'');
112       }
113
114       // Try "try harder" mode
115       try {
116         result = barcodeReader.decode(source, TRY_HARDER_HINT);
117       } catch (ReaderException re) {
118         if (passed) {
119           fail("Normal mode succeed but \"try harder\" failed");
120         }
121         continue;
122       }
123       assertEquals("Normal mode succeed but \"try harder\" failed", expectedFormat, result.getBarcodeFormat());
124       assertEquals("Normal mode succeed but \"try harder\" failed", expectedText, result.getText());
125     }
126
127     System.out.println(passedCount + " of " + imageFiles.length + " images passed");
128     assertTrue("Too many images failed", passedCount >= (int) (imageFiles.length * passPercent));
129   }
130
131   private static String readFileAsString(File file) throws IOException {
132     StringBuilder result = new StringBuilder();
133     InputStreamReader reader = new InputStreamReader(new FileInputStream(file), "UTF-8");
134     try {
135       char[] buffer = new char[256];
136       int charsRead;
137       while ((charsRead = reader.read(buffer)) > 0) {
138         result.append(buffer, 0, charsRead);
139       }
140     } finally {
141       reader.close();
142     }
143     return result.toString();
144   }
145
146 }