Image conversion (BMP2PSP / BMP2c) resulting in corruption?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
Josh1billion
Posts: 32
Joined: Tue Jul 12, 2005 8:45 am
Location: Wisconsin, USA
Contact:

Image conversion (BMP2PSP / BMP2c) resulting in corruption?

Post by Josh1billion »

I am trying to convert a bitmap image to the PSP-compatible unsigned short array format.

I have used two applications (from different sources but they do the same thing basically): BMP2PSP (which came with some SDK I downloaded I think) and BMP2c ( from http://www.ice-d.com/products/products_bmp2c.html ).

Both have resulted in the same problem: the image is nearly flawless, except some pixels are out of place in this way: I have an image of a simple circle/ball, and it looks like the ball was cut in half diagonally and the halves' positions were swapped.

I have used the JPG 2 PSP converter here: http://www.psp.to/tools/ and it does not have that problem. The only problem with using the JPG converter is that JPG images get blurred when you save them as most of you will know (in Windows, not just on the PSP of course). That means the pixels will not be crystal-clear, which is a problem because I'm trying to use transparency in my Breakout game.

Thanks in advance.
Josh1billion - PHP, C++, PSP programmer.
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

bmp's not a very nice format. I see that bmp2c only works on 256 colour bitmaps. bmp (in a file) has a requirement that each scanline is padded to 32bits (4 pixels). bmp2c doesn't do this properly. The only way to fix it without changing bmp2c is to make your graphic a multiple of 4 pixels wide. That should fix it.

Jim
Tim
Posts: 38
Joined: Tue Jul 12, 2005 4:40 am

Post by Tim »

ector's got a program he wrote for doing texture conversions: http://www.dtek.chalmers.se/~tronic/PSPTexTool.zip

I haven't gotten a chance to play around with it much yet, but it might be what you're looking for.
User avatar
cwbowron
Posts: 76
Joined: Fri May 06, 2005 4:22 am
Location: East Lansing, MI
Contact:

Post by cwbowron »

I use ConvImage16 but I do not know who wrote it, or where I got it. It converts from a variety of formats to a unsigned short array suitable for the psp.

You can grab it at http://www.cse.msu.edu/~bowronch/ConvImage16.zip
ector
Posts: 195
Joined: Thu May 12, 2005 10:22 pm

Post by ector »

If you choose 1 mipmap, the right 16bit color format and disable swizzling, my texture converter can be used for regular bitmaps to copy to the framebuffer if you also strip off or ignore the header, which should be 32 bytes in this case. I should probably add functionality to export raw bitmaps and maybe C files too in addition to my texture format.
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

Another solution is to load the free Java SDK from Sun and use this class, like in my Snake game, which can convert JPG, PNG (which you should use, if you want lossless image quality with alpha channel information) and all other graphics formats, which are supported by Java:

Code: Select all


import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;

public class GraphicsTo32BitRaw {

	public static void main(String args[]) throws Exception {
		// check arguments
		if (args.length != 1) {
			System.out.println("Usage: java GraphicsTo16BitRaw pic.png");
			return;
		}

		// load image
		String filename = args[0];
		Image image = ImageIO.read(new File(filename));

		// determine pixels
		int w = image.getWidth(null);
		int h = image.getHeight(null);
		int[] pixels = new int[w * h];
		PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
		try {
			pg.grabPixels();
		} catch (InterruptedException e) {
		}

		// save as raw data
		try {
			// create pixels buffer
			byte [] outBuffer = new byte[w*h*4];
			int i = 0;
			for &#40;int y = 0; y < h; y++&#41; &#123;
				StringBuffer line = new StringBuffer&#40;&#41;;
				for &#40;int x = 0; x < w; x++&#41; &#123;
					int color = pixels&#91;y * w + x&#93;;
					int blue = color & 0xff;
					int green = &#40;color >> 8&#41; & 0xff;
					int red = &#40;color >> 16&#41; & 0xff;
					int alpha = color >> 24;
					int value = red | &#40;green << 8&#41; | &#40;blue << 16&#41; | &#40;alpha << 24&#41;;
					outBuffer&#91;i++&#93; = &#40;byte&#41; red;
					outBuffer&#91;i++&#93; = &#40;byte&#41; green;
					outBuffer&#91;i++&#93; = &#40;byte&#41; blue;
					outBuffer&#91;i++&#93; = &#40;byte&#41; alpha;
				&#125;
			&#125;

			// write
			String name = filename.substring&#40;0, filename.length&#40;&#41; - 4&#41;;
			FileOutputStream out = new FileOutputStream&#40;name + ".raw"&#41;;
			out.write&#40;outBuffer&#41;;
			out.close&#40;&#41;;
		&#125; catch &#40;IOException e&#41; &#123;
			System.out.println&#40;"error while writing"&#41;;
			e.printStackTrace&#40;&#41;;
		&#125;
	&#125;
&#125;
Then your makefile could look like this and all png files are converted to .o-files and linked to your application:

Code: Select all

TARGET = snake
OBJS = snake.o \
       background.o apple.o fly.o \
       bodyLB.o bodyLT.o bodyRT.o bodyLR.o bodyRB.o bodyTB.o \
       headB.o headR.o headL.o headT.o \
       tailB.o tailR.o tailL.o tailT.o

INCDIR = 
CFLAGS = -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

LIBDIR =
LIBS =
LDFLAGS =

EXTRA_TARGETS = GraphicsTo32BitRaw.class EBOOT.PBP
PSP_EBOOT_TITLE = Snake v1.1
PSP_EBOOT_ICON = title-icon.png

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak

.SUFFIXES&#58; .png .java .class

.png.o&#58;
	java GraphicsTo32BitRaw $<
	bin2o -i $*.raw $@ $*

.java.class&#58;
	javac $<
From within your application just add a "extern u32 background_start[]" in your source, if you have an image with the name "background.png". For drawing with transparency, you can write something like this:

Code: Select all

void plotCellImage&#40;int x, int y, u32* image&#41;
&#123;
	u32* vram = pgGetVramAddr&#40;x * 16, y * 16&#41;;
	int xo, yo;
	for &#40;yo = 0; yo < 16; yo++&#41; &#123;
		for &#40;xo = 0; xo < 16; xo++&#41; &#123;
			if &#40;!IS_ALPHA&#40;*image&#41;&#41; &#123;
				vram&#91;xo + yo * PSP_LINE_SIZE&#93; = *image;
			&#125; else vram&#91;xo + yo * PSP_LINE_SIZE&#93; = background_start&#91;16*x + xo + &#40;16*y + yo&#41; * SCREEN_WIDTH&#93;;
			image++;
		&#125;
	&#125;
&#125;
with "#define IS_ALPHA(value) (((value)&0xff000000)==0)".
User avatar
Josh1billion
Posts: 32
Joined: Tue Jul 12, 2005 8:45 am
Location: Wisconsin, USA
Contact:

Post by Josh1billion »

cwbowron wrote:I use ConvImage16 but I do not know who wrote it, or where I got it. It converts from a variety of formats to a unsigned short array suitable for the psp.

You can grab it at http://www.cse.msu.edu/~bowronch/ConvImage16.zip
Thanks, that worked perfectly. :)
Josh1billion - PHP, C++, PSP programmer.
Post Reply