OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [imageio/] [png/] [PNGFilter.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* PNGFilter.java -- PNG image filters.
2
   Copyright (C) 2006 Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.javax.imageio.png;
39
 
40
/**
41
 * A utility class of static methods implementing the PNG filtering algorithms.
42
 */
43
public class PNGFilter
44
{
45
 
46
  public static final byte FILTER_NONE = 0;
47
  public static final byte FILTER_SUB = 1;
48
  public static final byte FILTER_UP = 2;
49
  public static final byte FILTER_AVERAGE = 3;
50
  public static final byte FILTER_PAETH = 4;
51
 
52
  /**
53
   * Return whether a filter should be used or FILTER_NONE,
54
   * following the recommendations in the PNG spec.
55
   */
56
  public static boolean useFilter( PNGHeader header )
57
  {
58
    switch( header.getColorType() )
59
      {
60
      case PNGHeader.INDEXED:
61
        return false;
62
 
63
      case PNGHeader.GRAYSCALE:
64
      case PNGHeader.RGB:
65
        if( header.bytesPerPixel() <= 1 )
66
          return false;
67
      case PNGHeader.GRAYSCALE_WITH_ALPHA:
68
      case PNGHeader.RGB_WITH_ALPHA:
69
      default:
70
        return true;
71
      }
72
  }
73
 
74
  /**
75
   * Heuristic for adaptively choosing a filter, following the scheme
76
   * suggested in the PNG spec.
77
   * @return a fiter type.
78
   */
79
  public static byte chooseFilter( byte[] scanline, byte[] lastScanline,
80
                                  int bpp)
81
 
82
  {
83
    long[] values = new long[5];
84
    int idx = 0;
85
    for( int i = 0; i < 5; i++ )
86
      {
87
        byte[] filtered = filterScanline((byte)i, scanline, lastScanline, bpp);
88
        values[i] = 0;
89
        for(int j = 0; j < filtered.length; j++ )
90
          values[i] += (int)(filtered[j] & 0xFF);
91
        if( values[ idx ] > values[i] )
92
          idx = i;
93
      }
94
    return (byte)idx;
95
  }
96
 
97
  /**
98
   * Filter a scanline.
99
   */
100
  public static byte[] filterScanline( byte filtertype, byte[] scanline,
101
                                       byte[] lastScanline, int bpp)
102
  {
103
    int stride = scanline.length;
104
    byte[] out = new byte[ stride ];
105
    switch( filtertype )
106
      {
107
      case FILTER_SUB:
108
        for( int i = 0; i < bpp; i++)
109
          out[ i ] = scanline[ i ];
110
 
111
        for( int i = bpp; i < stride; i++ )
112
          out[i] = (byte)(scanline[ i ] -
113
                          scanline[ i - bpp ]);
114
        break;
115
 
116
      case FILTER_UP:
117
        for( int i = 0; i < stride; i++ )
118
          out[ i ] = (byte)(scanline[ i ] - lastScanline[ i ]);
119
        break;
120
 
121
      case FILTER_AVERAGE:
122
        for( int i = 0; i < bpp; i++)
123
          out[ i ] = (byte)((scanline[ i ] & 0xFF) - ((lastScanline[ i ] & 0xFF) >> 1));
124
        for( int i = bpp; i < stride; i++ )
125
          out[ i ] = (byte)((scanline[ i ] & 0xFF) -
126
                            (((scanline[ i - bpp ] & 0xFF) +
127
                              (lastScanline[ i ] & 0xFF)) >> 1));
128
        break;
129
 
130
      case FILTER_PAETH:
131
        for( int i = 0; i < stride; i++ )
132
          {
133
            int x;
134
            {
135
              int a, b, c;
136
              if( i >= bpp )
137
                {
138
                  a = (scanline[ i - bpp ] & 0xFF); // left
139
                  c = (lastScanline[ i - bpp ] & 0xFF); // upper-left
140
                }
141
              else
142
                a = c = 0;
143
              b = (lastScanline[ i ] & 0xFF); // up
144
 
145
              int p = (a + b - c);        // initial estimate
146
              // distances to a, b, c
147
              int pa = (p > a) ? p - a : a - p;
148
              int pb = (p > b) ? p - b : b - p;
149
              int pc = (p > c) ? p - c : c - p;
150
              // return nearest of a,b,c,
151
              // breaking ties in order a,b,c.
152
              if( pa <= pb && pa <= pc ) x = a;
153
              else { if( pb <= pc ) x = b;
154
                else x = c;
155
              }
156
            }
157
            out[ i ] = (byte)(scanline[ i ] - x);
158
          }
159
        break;
160
      default:
161
      case FILTER_NONE:
162
        return scanline;
163
      }
164
    return out;
165
  }
166
 
167
  /**
168
   * Unfilter a scanline.
169
   */
170
  public static byte[] unFilterScanline( int filtertype, byte[] scanline,
171
                                         byte[] lastScanline, int bpp)
172
  {
173
    int stride = scanline.length;
174
    byte[] out = new byte[ stride ];
175
    switch( filtertype )
176
      {
177
 
178
      case FILTER_NONE:
179
        System.arraycopy( scanline, 0, out, 0, stride );
180
        break;
181
 
182
      case FILTER_SUB:
183
        for( int i = 0; i < bpp; i++)
184
          out[ i ] = scanline[ i ];
185
 
186
        for( int i = bpp; i < stride; i++ )
187
          out[ i ] = (byte)(scanline[ i ] +
188
                            out[ i - bpp ]);
189
        break;
190
 
191
      case FILTER_UP:
192
        for( int i = 0; i < stride; i++ )
193
          out[ i ] = (byte)(scanline[ i ] + lastScanline[ i ]);
194
        break;
195
 
196
      case FILTER_AVERAGE:
197
        for( int i = 0; i < bpp; i++)
198
          out[ i ] = (byte)((scanline[ i ] & 0xFF) + ((lastScanline[ i ] & 0xFF) >> 1));
199
        for( int i = bpp; i < stride; i++ )
200
          out[ i ] = (byte)((scanline[ i ] & 0xFF) +
201
                            (((out[ i - bpp ] & 0xFF) + (lastScanline[ i ] & 0xFF)) >> 1));
202
        break;
203
 
204
      case FILTER_PAETH:
205
        for( int i = 0; i < stride; i++ )
206
          {
207
            int x;
208
            {
209
              int a, b, c;
210
              if( i >= bpp )
211
                {
212
                  a = (out[ i - bpp ] & 0xFF); // left
213
                  c = (lastScanline[ i - bpp ] & 0xFF); // upper-left
214
                }
215
              else
216
                a = c = 0;
217
              b = (lastScanline[ i ] & 0xFF); // up
218
 
219
              int p = (a + b - c);        // initial estimate
220
              // distances to a, b, c
221
              int pa = (p > a) ? p - a : a - p;
222
              int pb = (p > b) ? p - b : b - p;
223
              int pc = (p > c) ? p - c : c - p;
224
              // return nearest of a,b,c,
225
              // breaking ties in order a,b,c.
226
              if( pa <= pb && pa <= pc ) x = a;
227
              else { if( pb <= pc ) x = b;
228
                else x = c;
229
              }
230
            }
231
            out[ i ] = (byte)(scanline[ i ] + x);
232
          }
233
        break;
234
      }
235
    return out;
236
  }
237
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.