1 7 8 package com.sun.imageio.plugins.png; 9 10 13 public class RowFilter { 14 15 private static final int abs(int x) { 16 return (x < 0) ? -x : x; 17 } 18 19 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 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 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 |