KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > imageio > plugins > png > RowFilter


1 /*
2  * @(#)RowFilter.java 1.9 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.imageio.plugins.png;
9
10 /**
11  * @version 0.5
12  */

13 public class RowFilter {
14
15     private static final int abs(int x) {
16         return (x < 0) ? -x : x;
17     }
18
19     // Returns the sum of absolute differences
20
protected static int subFilter(byte[] currRow,
21                                    byte[] subFilteredRow,
22                                    int bytesPerPixel,
23                                    int bytesPerRow) {
24         int badness = 0;
25         for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
26             int curr = currRow[i] & 0xff;
27             int left = currRow[i - bytesPerPixel] & 0xff;
28             int difference = curr - left;
29             subFilteredRow[i] = (byte)difference;
30             
31             badness += abs(difference);
32         }
33
34         return badness;
35     }
36
37     // Returns the sum of absolute differences
38
protected static int upFilter(byte[] currRow,
39                                   byte[] prevRow,
40                                   byte[] upFilteredRow,
41                                   int bytesPerPixel,
42                                   int bytesPerRow) {
43         int badness = 0;
44         for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
45             int curr = currRow[i] & 0xff;
46             int up = prevRow[i] & 0xff;
47             int difference = curr - up;
48             upFilteredRow[i] = (byte)difference;
49             
50             badness += abs(difference);
51         }
52         
53         return badness;
54     }
55
56     protected final int paethPredictor(int a, int b, int c) {
57         int p = a + b - c;
58         int pa = abs(p - a);
59         int pb = abs(p - b);
60         int pc = abs(p - c);
61
62         if ((pa <= pb) && (pa <= pc)) {
63             return a;
64         } else if (pb <= pc) {
65             return b;
66         } else {
67             return c;
68         }
69     }
70
71     public int filterRow(int colorType,
72                          byte[] currRow,
73                          byte[] prevRow,
74                          byte[][] scratchRows,
75                          int bytesPerRow,
76                          int bytesPerPixel) {
77
78         // Use type 0 for palette images
79
if (colorType != PNGImageReader.PNG_COLOR_PALETTE) {
80             System.arraycopy(currRow, bytesPerPixel,
81                              scratchRows[0], bytesPerPixel,
82                              bytesPerRow);
83             return 0;
84         }
85
86         int[] filterBadness = new int[5];
87         for (int i = 0; i < 5; i++) {
88             filterBadness[i] = Integer.MAX_VALUE;
89         }
90         
91         {
92             int badness = 0;
93             
94             for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
95                 int curr = currRow[i] & 0xff;
96                 badness += curr;
97             }
98             
99             filterBadness[0] = badness;
100         }
101         
102         {
103             byte[] subFilteredRow = scratchRows[1];
104             int badness = subFilter(currRow,
105                                     subFilteredRow,
106                                     bytesPerPixel,
107                                     bytesPerRow);
108             
109             filterBadness[1] = badness;
110         }
111         
112         {
113             byte[] upFilteredRow = scratchRows[2];
114             int badness = upFilter(currRow,
115                                    prevRow,
116                                    upFilteredRow,
117                                    bytesPerPixel,
118                                    bytesPerRow);
119             
120             filterBadness[2] = badness;
121         }
122         
123         {
124             byte[] averageFilteredRow = scratchRows[3];
125             int badness = 0;
126
127             for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
128                 int curr = currRow[i] & 0xff;
129                 int left = currRow[i - bytesPerPixel] & 0xff;
130                 int up = prevRow[i] & 0xff;
131                 int difference = curr - (left + up)/2;;
132                 averageFilteredRow[i] = (byte)difference;
133                 
134                 badness += abs(difference);
135             }
136             
137             filterBadness[3] = badness;
138         }
139         
140         {
141             byte[] paethFilteredRow = scratchRows[4];
142             int badness = 0;
143             
144             for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
145                 int curr = currRow[i] & 0xff;
146                 int left = currRow[i - bytesPerPixel] & 0xff;
147                 int up = prevRow[i] & 0xff;
148                 int upleft = prevRow[i - bytesPerPixel] & 0xff;
149                 int predictor = paethPredictor(left, up, upleft);
150                 int difference = curr - predictor;
151                 paethFilteredRow[i] = (byte)difference;
152                 
153                 badness += abs(difference);
154             }
155             
156             filterBadness[4] = badness;
157         }
158         
159         int minBadness = filterBadness[0];
160         int filterType = 0;
161
162         for (int i = 1; i < 5; i++) {
163             if (filterBadness[i] < minBadness) {
164                 minBadness = filterBadness[i];
165                 filterType = i;
166             }
167         }
168
169         if (filterType == 0) {
170             System.arraycopy(currRow, bytesPerPixel,
171                              scratchRows[0], bytesPerPixel,
172                              bytesPerRow);
173         }
174         
175         return filterType;
176     }
177 }
178
Popular Tags