Load pixels directly into sprite definition, not sure what these offsets are
This commit is contained in:
@@ -30,35 +30,16 @@
|
||||
|
||||
package net.runelite.cache.definitions;
|
||||
|
||||
import net.runelite.cache.definitions.loaders.SpriteLoader;
|
||||
|
||||
public class SpriteDefinition
|
||||
{
|
||||
private SpriteLoader loader;
|
||||
private int offsetX;
|
||||
private int offsetY;
|
||||
private int width;
|
||||
private int height;
|
||||
private byte[] pixels; // indexes into palette
|
||||
private byte[] alphas;
|
||||
private int[] pixels;
|
||||
private int maxWidth;
|
||||
private int maxHeight;
|
||||
|
||||
public SpriteDefinition(SpriteLoader loader)
|
||||
{
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public SpriteLoader getLoader()
|
||||
{
|
||||
return loader;
|
||||
}
|
||||
|
||||
public void setLoader(SpriteLoader loader)
|
||||
{
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public int getOffsetX()
|
||||
{
|
||||
return offsetX;
|
||||
@@ -99,26 +80,16 @@ public class SpriteDefinition
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public byte[] getPixels()
|
||||
public int[] getPixels()
|
||||
{
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public void setPixels(byte[] pixels)
|
||||
public void setPixels(int[] pixels)
|
||||
{
|
||||
this.pixels = pixels;
|
||||
}
|
||||
|
||||
public byte[] getAlphas()
|
||||
{
|
||||
return alphas;
|
||||
}
|
||||
|
||||
public void setAlphas(byte[] alphas)
|
||||
{
|
||||
this.alphas = alphas;
|
||||
}
|
||||
|
||||
public int getMaxWidth()
|
||||
{
|
||||
return maxWidth;
|
||||
|
||||
@@ -38,31 +38,29 @@ public class SpriteLoader
|
||||
public static final int FLAG_VERTICAL = 0b01;
|
||||
public static final int FLAG_ALPHA = 0b10;
|
||||
|
||||
private SpriteDefinition[] sprites;
|
||||
|
||||
private int[] loadedPalette;
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
public void load(InputStream stream)
|
||||
public SpriteDefinition[] load(InputStream stream)
|
||||
{
|
||||
stream.setOffset(stream.getLength() - 2);
|
||||
int spriteCount = stream.readUnsignedShort();
|
||||
|
||||
sprites = new SpriteDefinition[spriteCount];
|
||||
for (int i = 0; i < spriteCount; ++i)
|
||||
{
|
||||
sprites[i] = new SpriteDefinition(this);
|
||||
}
|
||||
SpriteDefinition[] sprites = new SpriteDefinition[spriteCount];
|
||||
|
||||
// 2 for size
|
||||
// 5 for width, height, palette length
|
||||
// + 8 bytes per sprite for offset x/y, width, and height
|
||||
stream.setOffset(stream.getLength() - 7 - spriteCount * 8);
|
||||
|
||||
width = stream.readUnsignedShort();
|
||||
height = stream.readUnsignedShort();
|
||||
int paletteLength = (stream.readUnsignedByte() & 255) + 1;
|
||||
// max width and height
|
||||
int width = stream.readUnsignedShort();
|
||||
int height = stream.readUnsignedShort();
|
||||
int paletteLength = stream.readUnsignedByte() + 1;
|
||||
|
||||
for (int i = 0; i < spriteCount; ++i)
|
||||
{
|
||||
sprites[i] = new SpriteDefinition();
|
||||
sprites[i].setMaxWidth(width);
|
||||
sprites[i].setMaxHeight(height);
|
||||
}
|
||||
|
||||
for (int i = 0; i < spriteCount; ++i)
|
||||
{
|
||||
@@ -86,15 +84,15 @@ public class SpriteLoader
|
||||
|
||||
// same as above + 3 bytes for each palette entry, except for the first one (which is transparent)
|
||||
stream.setOffset(stream.getLength() - 7 - spriteCount * 8 - (paletteLength - 1) * 3);
|
||||
loadedPalette = new int[paletteLength];
|
||||
int[] palette = new int[paletteLength];
|
||||
|
||||
for (int i = 1; i < paletteLength; ++i)
|
||||
{
|
||||
loadedPalette[i] = stream.read24BitInt();
|
||||
palette[i] = stream.read24BitInt();
|
||||
|
||||
if (loadedPalette[i] == 0)
|
||||
if (palette[i] == 0)
|
||||
{
|
||||
loadedPalette[i] = 1;
|
||||
palette[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,10 +101,9 @@ public class SpriteLoader
|
||||
for (int i = 0; i < spriteCount; ++i)
|
||||
{
|
||||
SpriteDefinition def = sprites[i];
|
||||
int width = def.getWidth();
|
||||
int height = def.getHeight();
|
||||
// XXX OFFSETS
|
||||
int dimension = width * height;
|
||||
int spriteWidth = def.getWidth();
|
||||
int spriteHeight = def.getHeight();
|
||||
int dimension = spriteWidth * spriteHeight;
|
||||
byte[] pixelPaletteIndicies = new byte[dimension];
|
||||
byte[] pixelAlphas = new byte[dimension];
|
||||
|
||||
@@ -123,11 +120,11 @@ public class SpriteLoader
|
||||
else
|
||||
{
|
||||
// read vertically
|
||||
for (int j = 0; j < width; ++j)
|
||||
for (int j = 0; j < spriteWidth; ++j)
|
||||
{
|
||||
for (int k = 0; k < height; ++k)
|
||||
for (int k = 0; k < spriteHeight; ++k)
|
||||
{
|
||||
pixelPaletteIndicies[width * k + j] = stream.readByte();
|
||||
pixelPaletteIndicies[spriteWidth * k + j] = stream.readByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,11 +143,11 @@ public class SpriteLoader
|
||||
else
|
||||
{
|
||||
// read vertically
|
||||
for (int j = 0; j < width; ++j)
|
||||
for (int j = 0; j < spriteWidth; ++j)
|
||||
{
|
||||
for (int k = 0; k < height; ++k)
|
||||
for (int k = 0; k < spriteHeight; ++k)
|
||||
{
|
||||
pixelAlphas[width * k + j] = stream.readByte();
|
||||
pixelAlphas[spriteWidth * k + j] = stream.readByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,18 +164,19 @@ public class SpriteLoader
|
||||
}
|
||||
}
|
||||
|
||||
def.setPixels(pixelPaletteIndicies);
|
||||
def.setAlphas(pixelAlphas);
|
||||
}
|
||||
}
|
||||
int[] pixels = new int[dimension];
|
||||
|
||||
// build argb pixels from palette/alphas
|
||||
for (int j = 0; j < dimension; ++j)
|
||||
{
|
||||
int index = pixelPaletteIndicies[j] & 0xFF;
|
||||
|
||||
pixels[j] = palette[index] | (pixelAlphas[j] << 24);
|
||||
}
|
||||
|
||||
def.setPixels(pixels);
|
||||
}
|
||||
|
||||
public SpriteDefinition[] getSprites()
|
||||
{
|
||||
return sprites;
|
||||
}
|
||||
|
||||
public int[] getLoadedPalette()
|
||||
{
|
||||
return loadedPalette;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam <Adam@sigterm.info>
|
||||
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Adam <Adam@sigterm.info> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.cache.renderable;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import net.runelite.cache.definitions.SpriteDefinition;
|
||||
|
||||
public class RGBSprite
|
||||
{
|
||||
private int offsetY;
|
||||
private int spriteWidth;
|
||||
private int spriteHeight;
|
||||
private int offsetX;
|
||||
private int maxHeight;
|
||||
private int maxWidth;
|
||||
private int[] pixels;
|
||||
|
||||
RGBSprite()
|
||||
{
|
||||
}
|
||||
|
||||
public int getOffsetY()
|
||||
{
|
||||
return offsetY;
|
||||
}
|
||||
|
||||
public int getSpriteWidth()
|
||||
{
|
||||
return spriteWidth;
|
||||
}
|
||||
|
||||
public int getSpriteHeight()
|
||||
{
|
||||
return spriteHeight;
|
||||
}
|
||||
|
||||
public int getOffsetX()
|
||||
{
|
||||
return offsetX;
|
||||
}
|
||||
|
||||
public int getMaxHeight()
|
||||
{
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
public int getMaxWidth()
|
||||
{
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
public int[] getPixels()
|
||||
{
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public static RGBSprite fromSpriteDefinition(SpriteDefinition def)
|
||||
{
|
||||
RGBSprite sprite = new RGBSprite();
|
||||
|
||||
sprite.maxWidth = def.getMaxWidth();
|
||||
sprite.maxHeight = def.getMaxHeight();
|
||||
sprite.offsetX = def.getOffsetX();
|
||||
sprite.offsetY = def.getOffsetY();
|
||||
sprite.spriteWidth = def.getWidth();
|
||||
sprite.spriteHeight = def.getHeight();
|
||||
|
||||
int dimension = sprite.spriteWidth * sprite.spriteHeight;
|
||||
byte[] pixels = def.getPixels();
|
||||
|
||||
int[] palette = def.getLoader().getLoadedPalette();
|
||||
byte[] alphas = def.getAlphas();
|
||||
|
||||
sprite.pixels = new int[dimension];
|
||||
|
||||
for (int pos = 0; pos < dimension; ++pos)
|
||||
{
|
||||
int index = pixels[pos] & 0xff;
|
||||
|
||||
sprite.pixels[pos] = palette[index] | (alphas[pos] << 24);
|
||||
}
|
||||
|
||||
return sprite;
|
||||
}
|
||||
|
||||
public BufferedImage getBufferedImage()
|
||||
{
|
||||
BufferedImage bi = new BufferedImage(spriteWidth, spriteHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
bi.setRGB(0, 0, spriteWidth, spriteHeight, pixels, 0, spriteWidth);
|
||||
return bi;
|
||||
}
|
||||
}
|
||||
@@ -28,14 +28,12 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.cache.loaders;
|
||||
package net.runelite.cache;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageIO;
|
||||
import net.runelite.cache.IndexType;
|
||||
import net.runelite.cache.StoreLocation;
|
||||
import net.runelite.cache.definitions.SpriteDefinition;
|
||||
import net.runelite.cache.definitions.loaders.SpriteLoader;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
@@ -43,7 +41,6 @@ import net.runelite.cache.fs.File;
|
||||
import net.runelite.cache.fs.Index;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import net.runelite.cache.io.InputStream;
|
||||
import net.runelite.cache.renderable.RGBSprite;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -51,9 +48,9 @@ import org.junit.rules.TemporaryFolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SpriteLoaderTest
|
||||
public class SpriteDumperTest
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpriteLoaderTest.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpriteDumperTest.class);
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
|
||||
@@ -82,24 +79,23 @@ public class SpriteLoaderTest
|
||||
byte[] contents = file.getContents();
|
||||
|
||||
SpriteLoader loader = new SpriteLoader();
|
||||
loader.load(new InputStream(contents));
|
||||
|
||||
SpriteDefinition[] defs = loader.getSprites();
|
||||
|
||||
for (int i = 0; i < defs.length; ++i)
|
||||
{
|
||||
RGBSprite sp = RGBSprite.fromSpriteDefinition(defs[i]);
|
||||
SpriteDefinition[] sprites = loader.load(new InputStream(contents));
|
||||
|
||||
int frame = 0;
|
||||
|
||||
for (SpriteDefinition def : sprites)
|
||||
{
|
||||
// I don't know why this happens
|
||||
if (sp.getSpriteHeight() <= 0 || sp.getSpriteWidth() <= 0)
|
||||
if (def.getHeight() <= 0 || def.getWidth() <= 0)
|
||||
continue;
|
||||
|
||||
BufferedImage image = sp.getBufferedImage();
|
||||
java.io.File targ = new java.io.File(outDir, a.getArchiveId() + "-" + i + ".png");
|
||||
BufferedImage image = getBufferedImage(def);
|
||||
java.io.File targ = new java.io.File(outDir, a.getArchiveId() + "-" + frame + ".png");
|
||||
targ.mkdirs();
|
||||
ImageIO.write(image, "png", targ);
|
||||
|
||||
++count;
|
||||
++frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,4 +104,11 @@ public class SpriteLoaderTest
|
||||
|
||||
logger.info("Dumped {} sprites to {}", count, outDir);
|
||||
}
|
||||
|
||||
private BufferedImage getBufferedImage(SpriteDefinition def)
|
||||
{
|
||||
BufferedImage bi = new BufferedImage(def.getWidth(), def.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
bi.setRGB(0, 0, def.getWidth(), def.getHeight(), def.getPixels(), 0, def.getWidth());
|
||||
return bi;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.cache.loaders;
|
||||
package net.runelite.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
Reference in New Issue
Block a user