| Conditions | 48 |
| Paths | > 20000 |
| Total Lines | 234 |
| Code Lines | 159 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 41 | function fromiconstring($ico) { |
||
| 42 | $this->error = "(unknown error)"; |
||
| 43 | $this->had_alpha = 0; |
||
| 44 | |||
| 45 | // Read header |
||
| 46 | if (strlen($ico) < 6) { |
||
| 47 | $this->error = "too short"; |
||
| 48 | return false; |
||
| 49 | } |
||
| 50 | $h = unpack("vzero/vtype/vnum", $ico); |
||
| 51 | |||
| 52 | // Must be ICO format with at least one image |
||
| 53 | if ($h["zero"] != 0 || $h["type"] != 1 || $h["num"] == 0) { |
||
| 54 | // See if we can just parse it with GD directly |
||
| 55 | // if it's not ICO format; maybe it was a mislabeled |
||
| 56 | // PNG or something. |
||
| 57 | $i = @imagecreatefromstring($ico); |
||
| 58 | if ($i) { |
||
| 59 | imagesavealpha($i, true); |
||
| 60 | return $i; |
||
| 61 | } |
||
| 62 | $this->error = "not ICO or other image"; |
||
| 63 | return false; |
||
| 64 | } |
||
| 65 | |||
| 66 | // Read directory entries to find the biggest image |
||
| 67 | $most_pixels = 0; |
||
| 68 | for ($i = 0; $i < $h["num"]; $i++) { |
||
| 69 | $entry = substr($ico, 6 + 16 * $i, 16); |
||
| 70 | if (!$entry || strlen($entry) < 16) { |
||
| 71 | continue; |
||
| 72 | } |
||
| 73 | $e = unpack("Cwidth/". |
||
| 74 | "Cheight/". |
||
| 75 | "Ccolors/". |
||
| 76 | "Czero/". |
||
| 77 | "vplanes/". |
||
| 78 | "vbpp/". |
||
| 79 | "Vsize/". |
||
| 80 | "Voffset/", |
||
| 81 | $entry); |
||
| 82 | if ($e["width"] == 0) { |
||
| 83 | $e["width"] = 256; |
||
| 84 | } |
||
| 85 | if ($e["height"] == 0) { |
||
| 86 | $e["height"] = 256; |
||
| 87 | } |
||
| 88 | if ($e["zero"] != 0) { |
||
| 89 | $this->error = "nonzero reserved field"; |
||
| 90 | return false; |
||
| 91 | } |
||
| 92 | $pixels = $e["width"] * $e["height"]; |
||
| 93 | if ($pixels > $most_pixels) { |
||
| 94 | $most_pixels = $pixels; |
||
| 95 | $most = $e; |
||
| 96 | } |
||
| 97 | } |
||
| 98 | if ($most_pixels == 0) { |
||
| 99 | $this->error = "no pixels"; |
||
| 100 | return false; |
||
| 101 | } |
||
| 102 | $e = $most; |
||
| 103 | |||
| 104 | // Extract image data |
||
| 105 | $data = substr($ico, $e["offset"], $e["size"]); |
||
| 106 | if (!$data || strlen($data) != $e["size"]) { |
||
| 107 | $this->error = "bad image data"; |
||
| 108 | return false; |
||
| 109 | } |
||
| 110 | |||
| 111 | // See if we can parse it (might be PNG format here) |
||
| 112 | $i = @imagecreatefromstring($data); |
||
| 113 | if ($i) { |
||
| 114 | imagesavealpha($img, true); |
||
| 115 | return $i; |
||
| 116 | } |
||
| 117 | |||
| 118 | // Must be a BMP. Parse it ourselves. |
||
| 119 | $img = imagecreatetruecolor($e["width"], $e["height"]); |
||
| 120 | imagesavealpha($img, true); |
||
| 121 | $bg = imagecolorallocatealpha($img, 255, 0, 0, 127); |
||
| 122 | imagefill($img, 0, 0, $bg); |
||
| 123 | |||
| 124 | // Skip over the BITMAPCOREHEADER or BITMAPINFOHEADER; |
||
| 125 | // we'll just assume the palette and pixel data follow |
||
| 126 | // in the most obvious format as described by the icon |
||
| 127 | // directory entry. |
||
| 128 | $bitmapinfo = unpack("Vsize", $data); |
||
| 129 | if ($bitmapinfo["size"] == 40) { |
||
| 130 | $info = unpack("Vsize/". |
||
| 131 | "Vwidth/". |
||
| 132 | "Vheight/". |
||
| 133 | "vplanes/". |
||
| 134 | "vbpp/". |
||
| 135 | "Vcompress/". |
||
| 136 | "Vsize/". |
||
| 137 | "Vxres/". |
||
| 138 | "Vyres/". |
||
| 139 | "Vpalcolors/". |
||
| 140 | "Vimpcolors/", $data); |
||
| 141 | if ($e["bpp"] == 0) { |
||
| 142 | $e["bpp"] = $info["bpp"]; |
||
| 143 | } |
||
| 144 | } |
||
| 145 | $data = substr($data, $bitmapinfo["size"]); |
||
| 146 | |||
| 147 | $height = $e["height"]; |
||
| 148 | $width = $e["width"]; |
||
| 149 | $bpp = $e["bpp"]; |
||
| 150 | |||
| 151 | // For indexed images, we only support 1, 4, or 8 BPP |
||
| 152 | switch ($bpp) { |
||
| 153 | case 1: |
||
| 154 | case 4: |
||
| 155 | case 8: |
||
| 156 | $indexed = 1; |
||
| 157 | break; |
||
| 158 | case 24: |
||
| 159 | case 32: |
||
| 160 | $indexed = 0; |
||
| 161 | break; |
||
| 162 | default: |
||
| 163 | $this->error = "bad BPP $bpp"; |
||
| 164 | return false; |
||
| 165 | } |
||
| 166 | |||
| 167 | $offset = 0; |
||
| 168 | if ($indexed) { |
||
| 169 | $palette = array(); |
||
| 170 | $this->all_transparent = 1; |
||
| 171 | for ($i = 0; $i < (1 << $bpp); $i++) { |
||
| 172 | $entry = substr($data, $i * 4, 4); |
||
| 173 | $palette[$i] = $this->get_color($entry, $img); |
||
| 174 | } |
||
| 175 | $offset = $i * 4; |
||
| 176 | |||
| 177 | // Hack for some icons: if everything was transparent, |
||
| 178 | // discard alpha channel. |
||
| 179 | if ($this->all_transparent) { |
||
| 180 | for ($i = 0; $i < (1 << $bpp); $i++) { |
||
| 181 | $palette[$i] &= 0xffffff; |
||
| 182 | } |
||
| 183 | } |
||
| 184 | } |
||
| 185 | |||
| 186 | // Assume image data follows in bottom-up order. |
||
| 187 | // First the "XOR" image |
||
| 188 | if ((strlen($data) - $offset) < ($bpp * $height * $width / 8)) { |
||
| 189 | $this->error = "short data"; |
||
| 190 | return false; |
||
| 191 | } |
||
| 192 | $XOR = array(); |
||
| 193 | for ($y = $height - 1; $y >= 0; $y--) { |
||
| 194 | $x = 0; |
||
| 195 | while ($x < $width) { |
||
| 196 | if (!$indexed) { |
||
| 197 | $bytes = $bpp / 8; |
||
| 198 | $entry = substr($data, $offset, $bytes); |
||
| 199 | $pixel = $this->get_color($entry, $img); |
||
| 200 | $XOR[$y][$x] = $pixel; |
||
| 201 | $x++; |
||
| 202 | $offset += $bytes; |
||
| 203 | } elseif ($bpp == 1) { |
||
| 204 | $p = ord($data[$offset]); |
||
| 205 | for ($b = 0x80; $b > 0; $b >>= 1) { |
||
| 206 | if ($p & $b) { |
||
| 207 | $pixel = $palette[1]; |
||
| 208 | } else { |
||
| 209 | $pixel = $palette[0]; |
||
| 210 | } |
||
| 211 | $XOR[$y][$x] = $pixel; |
||
| 212 | $x++; |
||
| 213 | } |
||
| 214 | $offset++; |
||
| 215 | } elseif ($bpp == 4) { |
||
| 216 | $p = ord($data[$offset]); |
||
| 217 | $pixel1 = $palette[$p >> 4]; |
||
| 218 | $pixel2 = $palette[$p & 0x0f]; |
||
| 219 | $XOR[$y][$x] = $pixel1; |
||
| 220 | $XOR[$y][$x + 1] = $pixel2; |
||
| 221 | $x += 2; |
||
| 222 | $offset++; |
||
| 223 | } elseif ($bpp == 8) { |
||
| 224 | $pixel = $palette[ord($data[$offset])]; |
||
| 225 | $XOR[$y][$x] = $pixel; |
||
| 226 | $x += 1; |
||
| 227 | $offset++; |
||
| 228 | } else { |
||
| 229 | $this->error = "bad BPP"; |
||
| 230 | return false; |
||
| 231 | } |
||
| 232 | } |
||
| 233 | // End of row padding |
||
| 234 | while ($offset & 3) { |
||
| 235 | $offset++; |
||
| 236 | } |
||
| 237 | } |
||
| 238 | |||
| 239 | // Now the "AND" image, which is 1 bit per pixel. Ignore |
||
| 240 | // if some of our image data already had alpha values, |
||
| 241 | // or if there isn't enough data left. |
||
| 242 | if ($this->had_alpha || |
||
| 243 | ((strlen($data) - $offset) < ($height * $width / 8))) { |
||
| 244 | // Just return what we've got |
||
| 245 | for ($y = 0; $y < $height; $y++) { |
||
| 246 | for ($x = 0; $x < $width; $x++) { |
||
| 247 | imagesetpixel($img, $x, $y, |
||
| 248 | $XOR[$y][$x]); |
||
| 249 | } |
||
| 250 | } |
||
| 251 | return $img; |
||
| 252 | } |
||
| 253 | |||
| 254 | // Mask what we have with the "AND" image |
||
| 255 | for ($y = $height - 1; $y >= 0; $y--) { |
||
| 256 | $x = 0; |
||
| 257 | while ($x < $width) { |
||
| 258 | for ($b = 0x80; |
||
| 259 | $b > 0 && $x < $width; $b >>= 1) { |
||
| 260 | if (!(ord($data[$offset]) & $b)) { |
||
| 261 | imagesetpixel($img, $x, $y, |
||
| 262 | $XOR[$y][$x]); |
||
| 263 | } |
||
| 264 | $x++; |
||
| 265 | } |
||
| 266 | $offset++; |
||
| 267 | } |
||
| 268 | |||
| 269 | // End of row padding |
||
| 270 | while ($offset & 3) { |
||
| 271 | $offset++; |
||
| 272 | } |
||
| 273 | } |
||
| 274 | return $img; |
||
| 275 | } |
||
| 277 | ?> |
||
Adding explicit visibility (
private,protected, orpublic) is generally recommend to communicate to other developers how, and from where this method is intended to be used.