Commits

Martin Karing committed 815d153

Fixed loading of PNG data using the TWL PNG loader

Comments (0)

Files changed (1)

trunk/Slick/src/org/newdawn/slick/opengl/PNGImageData.java

 import java.util.Arrays;
 
 import org.lwjgl.BufferUtils;
+import org.newdawn.slick.util.Log;
 
 /**
  * The PNG imge data source that is pure java reading PNGs
 	public ByteBuffer loadImage(InputStream fis, boolean flipped, boolean forceAlpha, int[] transparent) throws IOException {
 		if (transparent != null) {
 			forceAlpha = true;
-			//throw new IOException("Transparent color not support in custom PNG Decoder");
 		}
 		
 		PNGDecoder decoder = new PNGDecoder(fis);
 		height = decoder.getHeight();
 		texWidth = get2Fold(width);
 		texHeight = get2Fold(height);
-		//get the decoder's format
-		final PNGDecoder.Format decoderFormat = decoder.decideTextureFormat(PNGDecoder.Format.LUMINANCE);
-		if (decoderFormat == PNGDecoder.Format.RGB) {
-		    format = Format.RGB;
-		} else if (decoderFormat == PNGDecoder.Format.RGBA) {
-            format = Format.RGBA;
-		} else if (decoderFormat == PNGDecoder.Format.BGRA) {
-            format = Format.BGRA;
-        } else if (decoderFormat == PNGDecoder.Format.LUMINANCE) {
-            format = Format.GRAY;
-        } else if (decoderFormat == PNGDecoder.Format.LUMINANCE_ALPHA) {
-            format = Format.GRAYALPHA;
+
+        final PNGDecoder.Format decoderFormat;
+        if (forceAlpha) {
+            if (decoder.isRGB()) {
+                decoderFormat = decoder.decideTextureFormat(PNGDecoder.Format.RGBA);
+            } else {
+                decoderFormat = decoder.decideTextureFormat(PNGDecoder.Format.LUMINANCE_ALPHA);
+            }
         } else {
-            throw new IOException("Unsupported Image format.");
+            decoderFormat = decoder.decideTextureFormat(PNGDecoder.Format.LUMINANCE);
+        }
+
+        switch (decoderFormat) {
+            case RGB:
+                format = Format.RGB;
+                break;
+            case RGBA:
+                format = Format.RGBA;
+                break;
+            case BGRA:
+                format = Format.BGRA;
+                break;
+            case LUMINANCE:
+                format = Format.GRAY;
+                break;
+            case LUMINANCE_ALPHA:
+                format = Format.GRAYALPHA;
+                break;
+            default:
+                throw new IOException("Unsupported Image format.");
         }
 		
 		int perPixel = format.getColorComponents();
 		
 		// Get a pointer to the image memory
 		scratch = BufferUtils.createByteBuffer(texWidth * texHeight * perPixel);
-		decoder.decode(scratch, texWidth * perPixel, decoderFormat);
+
+        if (flipped) {
+            decoder.decodeFlipped(scratch, texWidth * perPixel, decoderFormat);
+        } else {
+		    decoder.decode(scratch, texWidth * perPixel, decoderFormat);
+        }
 
 		if (height < texHeight-1) {
 			int topOffset = (texHeight-1) * (texWidth*perPixel);
 				}
 			}
 		}
-		boolean hasAlpha = format.hasAlpha();
-		if (forceAlpha) {
-		    final int orgComp = format.getColorComponents();
-		    final int newComp = orgComp + 1;
-			ByteBuffer temp = BufferUtils.createByteBuffer(texWidth * texHeight * newComp);
-			for (int x=0;x<texWidth;x++) {
-				for (int y=0;y<texHeight;y++) {
-					int srcOffset = (y*orgComp)+(x*texHeight*orgComp);
-					int dstOffset = (y*newComp)+(x*texHeight*newComp);
-					
-					temp.position(dstOffset);
-					scratch.position(srcOffset);
-					for (int i = 0; i < orgComp; i++) {
-					    temp.put(scratch.get());
-					}
-					if ((x < getWidth()) && (y < getHeight())) {
-						temp.put((byte) 255);
-					} else {
-						temp.put((byte) 0);
-					}
-				}
-			}
-			
-			if (format == Format.RGB) {
-			    format = Format.RGBA;
-			} else if (format == Format.GRAY) {
-                format = Format.GRAYALPHA;
-            }
-			scratch = temp;
-		}
 
         scratch.position(0);
 		
-		if (!hasAlpha && transparent != null) {
+		if (transparent != null) {
 			// components will now be + 1
 			final int components = format.getColorComponents();
 
-			final int size = texWidth * texHeight * components;
-			boolean match;
+            if (transparent.length != components - 1) {
+                Log.warn("The amount of color components of the transparent color does not fit the number of color components of the actual image.");
+            }
 
-			for (int i = 0; i < size; i += components) {
-				match = true;
-				for (int c = 0; c < components - 1; c++) {
-					if (toInt(scratch.get(i + c)) != transparent[c]) {
-						match = false;
-						break;
-					}
-				}
-				if (match) {
-					scratch.put(i + components - 1, (byte) 0);
-				}
-			}
+            if (transparent.length < components - 1) {
+                Log.error("Failed to apply transparent color, not enough color values in color definition.");
+            } else {
+
+                final int size = texWidth * texHeight * components;
+                boolean match;
+
+                for (int i = 0; i < size; i += components) {
+                    match = true;
+                    for (int c = 0; c < components - 1; c++) {
+                        if (toInt(scratch.get(i + c)) != transparent[c]) {
+                            match = false;
+                            break;
+                        }
+                    }
+                    if (match) {
+                        scratch.put(i + components - 1, (byte) 0);
+                    }
+                }
+            }
 		}
 
 		scratch.position(0);