Skip to content

Commit

Permalink
Implement some missing Image methods, and do some small cleanups
Browse files Browse the repository at this point in the history
Image mutability is a bit more relaxed as well, allowing MIDP images
to also be mutable in a few cases where they shouldn't be. Just so
there's less code duplication with Nokia DirectGraphics/Utils.

Fixes #38 among others.
  • Loading branch information
AShiningRay committed Dec 21, 2024
1 parent 4a4e59d commit 20fb8b7
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 69 deletions.
13 changes: 4 additions & 9 deletions src/com/nokia/mid/ui/DirectUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,17 @@ public class DirectUtils

public static Image createImage(byte[] imageData, int imageOffset, int imageLength)
{
return Image.createNokiaImage(imageData, imageOffset, imageLength);
return Image.createImage(imageData, imageOffset, imageLength);
}

public static Image createImage(int width, int height, int ARGBcolor)
{
Image image = Image.createImage(width, height); // This one already creates a mutable image
PlatformGraphics gc = (PlatformGraphics)image.getGraphics();
gc.clearRect(0, 0, width, height);
gc.setAlphaRGB(ARGBcolor);
gc.fillRect(0,0, width, height);
return image;
return Image.createImage(width, height, ARGBcolor);
}

public static DirectGraphics getDirectGraphics(javax.microedition.lcdui.Graphics g)
public static DirectGraphics getDirectGraphics(Graphics g)
{
return (PlatformGraphics)g;
return (PlatformGraphics) g;
}

}
32 changes: 11 additions & 21 deletions src/javax/microedition/lcdui/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class Image
public int width;
public int height;


// TODO: This will create mutable images for both MIDP (shouldn't) and Nokia DirectGraphics (should)
public static Image createImage(byte[] imageData, int imageOffset, int imageLength) throws IllegalArgumentException
{
Mobile.log(Mobile.LOG_DEBUG, Image.class.getPackage().getName() + "." + Image.class.getSimpleName() + ": " + "Create Image from image data ");
Expand All @@ -43,19 +43,6 @@ public static Image createImage(byte[] imageData, int imageOffset, int imageLeng
return new PlatformImage(imageData, imageOffset, imageLength);
}

// The only difference here is that DirectUtils creates a mutable image, not an immutable one.
public static Image createNokiaImage(byte[] imageData, int imageOffset, int imageLength) throws IllegalArgumentException
{
Mobile.log(Mobile.LOG_DEBUG, Image.class.getPackage().getName() + "." + Image.class.getSimpleName() + ": " + "Create DirectUtils Image from image data ");
if (imageData == null) {throw new NullPointerException();}
if (imageOffset + imageLength > imageData.length) {throw new ArrayIndexOutOfBoundsException();}

PlatformImage img = new PlatformImage(imageData, imageOffset, imageLength);
img.setMutable(true);

return img;
}

public static Image createImage(Image source)
{
Mobile.log(Mobile.LOG_DEBUG, Image.class.getPackage().getName() + "." + Image.class.getSimpleName() + ": " + "Create Image from Image ");
Expand All @@ -64,16 +51,13 @@ public static Image createImage(Image source)
if (!source.isMutable()) { return source; }

// Else, create an immutable copy of the received image.
PlatformImage newSource = new PlatformImage(source);
newSource.setMutable(false);

return new PlatformImage(source);
}

public static Image createImage(Image img, int x, int y, int width, int height, int transform)
{
Mobile.log(Mobile.LOG_DEBUG, Image.class.getPackage().getName() + "." + Image.class.getSimpleName() + ": " + "Create Image from sub-image " + " img_w:" + Integer.toString(img.getWidth()) + " img_h:" + Integer.toString(img.getHeight()) + " x:" + Integer.toString(x) + " y:" + Integer.toString(y) + " width:" + Integer.toString(width) + " height:" + Integer.toString(height));
if (img == null) {throw new NullPointerException();}
if (img == null) { throw new NullPointerException(); }
if (x+width > img.getWidth() || y+height > img.getHeight()) {throw new IllegalArgumentException();}
if (width <= 0 || height <= 0) {throw new IllegalArgumentException();}

Expand All @@ -94,9 +78,15 @@ public static Image createImage(int width, int height)
Mobile.log(Mobile.LOG_DEBUG, Image.class.getPackage().getName() + "." + Image.class.getSimpleName() + ": " + "Create Image w,h " + width + ", " + height);
if (width <= 0 || height <= 0) {throw new IllegalArgumentException();}

PlatformImage img = new PlatformImage(width, height);
img.setMutable(true);
return img;
return new PlatformImage(width, height);
}

public static Image createImage(int width, int height, int ARGBcolor)
{
Mobile.log(Mobile.LOG_DEBUG, Image.class.getPackage().getName() + "." + Image.class.getSimpleName() + ": " + "Create Image w,h,color " + width + ", " + height + ", " + ARGBcolor);
if (width <= 0 || height <= 0) {throw new IllegalArgumentException();}

return new PlatformImage(width, height, ARGBcolor);
}

public static Image createImage(String name) throws IOException
Expand Down
108 changes: 72 additions & 36 deletions src/org/recompile/mobile/PlatformGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ public void drawPixels(short[] pixels, boolean transparency, int offset, int sca
{
for (int col = 0; col < width; col++)
{
int index = offset + row * scanlength + col;
int index = offset + (col) + (row * scanlength);
data[row * width + col] = pixelToColor(pixels[index], format);
if (!transparency) { data[row * width + col] &= 0x00FFFFFF; } // Clear the alpha channel
}
Expand Down Expand Up @@ -671,7 +671,6 @@ public void getPixels(byte[] pixels, byte[] transparencyMask, int offset, int sc

// Temporary canvas data array to read raw pixel data from.
int[] canvasData = ((DataBufferInt) canvas.getRaster().getDataBuffer()).getData();

// Just like DrawPixels(byte), we only handle BYTE_1_GRAY_VERTICAL and BYTE_1_GRAY yet
switch (format)
{
Expand Down Expand Up @@ -721,81 +720,118 @@ public void getPixels(int[] pixels, int offset, int scanlength, int x, int y, in

public void getPixels(short[] pixels, int offset, int scanlength, int x, int y, int width, int height, int format)
{
int i = offset;
for(int row=0; row<height; row++)
{
for (int col=0; col<width; col++)
{
pixels[i] = colorToShortPixel(canvas.getRGB(col+x, row+y), format);
i++;
int pixelIndex = offset + (col) + (row * scanlength);
pixels[pixelIndex] = colorToShortPixel(canvas.getRGB(col+x, row+y), format);
}
}
}

private int pixelToColor(short c, int format)
private int pixelToColor(short c, int format)
{
int a = 0xFF;
int r = 0;
int g = 0;
int b = 0;
switch(format)

switch (format)
{
case DirectGraphics.TYPE_USHORT_1555_ARGB:
a = ((c>>15) & 0x01)*0xFF;
r = (c>>10) & 0x1F; g = (c>>5) & 0x1F; b = c & 0x1F;
r = (r<<3)|(r>>2); g = (g<<3)|(g>>2); b = (b<<3)|(b>>2);
a = ((c >> 15) & 0x01) * 0xFF; // just 1 bit for alpha
r = (c >> 10) & 0x1F;
g = (c >> 5) & 0x1F;
b = c & 0x1F;
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
b = (b << 3) | (b >> 2);
break;
case DirectGraphics.TYPE_USHORT_444_RGB:
r = (c>>8) & 0xF; g = (c>>4) & 0xF; b = c & 0xF;
r = (r<<4)|r; g = (g<<4)|g; b = (b<<4)|b;
r = (c >> 8) & 0xF;
g = (c >> 4) & 0xF;
b = c & 0xF;
r = (r << 4) | r;
g = (g << 4) | g;
b = (b << 4) | b;
break;
case DirectGraphics.TYPE_USHORT_4444_ARGB:
a = (c>>12) & 0xF; r = (c>>8) & 0xF; g = (c>>4) & 0xF; b = c & 0xF;
a = (a<<4)|a; r = (r<<4)|r; g = (g<<4)|g; b = (b<<4)|b;
a = (c >> 12) & 0xF;
r = (c >> 8) & 0xF;
g = (c >> 4) & 0xF;
b = c & 0xF;
a = (a << 4) | a;
r = (r << 4) | r;
g = (g << 4) | g;
b = (b << 4) | b;
break;
case DirectGraphics.TYPE_USHORT_555_RGB:
r = (c>>10) & 0x1F; g = (c>>5) & 0x1F; b = c & 0x1F;
r = (r<<3)|(r>>2); g = (g<<3)|(g>>2); b = (b<<3)|(b>>2);
r = (c >> 10) & 0x1F;
g = (c >> 5) & 0x1F;
b = c & 0x1F;
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
b = (b << 3) | (b >> 2);
break;
case DirectGraphics.TYPE_USHORT_565_RGB:
r = (c>>11) & 0x1F; g = (c>>5) & 0x3F; b = c & 0x1F;
r = (r<<3)|(r>>2); g = (g<<2)|(g>>4); b = (b<<3)|(b>>2);
r = (c >> 11) & 0x1F;
g = (c >> 5) & 0x3F;
b = c & 0x1F;
r = (r << 3) | (r >> 2);
g = (g << 2) | (g >> 4);
b = (b << 3) | (b >> 2);
break;
default:
throw new IllegalArgumentException("Unsupported format: " + format);
}
return (a<<24) | (r<<16) | (g<<8) | b;

return (a << 24) | (r << 16) | (g << 8) | b;
}

private short colorToShortPixel(int c, int format)
private short colorToShortPixel(int c, int format)
{
int a = 0;
int r = 0;
int g = 0;
int b = 0;
int a, r, g, b;
int out = 0;
switch(format)

switch (format)
{
case DirectGraphics.TYPE_USHORT_1555_ARGB:
a=c>>>31; r=((c>>19)&0x1F); g=((c>>11)&0x1F); b=((c>>3)&0x1F);
out=(a<<15)|(r<<10)|(g<<5)|b;
a = (c >>> 31) & 0x1;
r = (c >> 19) & 0x1F;
g = (c >> 11) & 0x1F;
b = (c >> 3) & 0x1F;
out = (a << 15) | (r << 10) | (g << 5) | b;
break;
case DirectGraphics.TYPE_USHORT_444_RGB:
r=((c>>20)&0xF); g=((c>>12)&0xF); b=((c>>4)&0xF);
out=(r<<8)|(g<<4)|b;
r = (c >> 20) & 0xF;
g = (c >> 12) & 0xF;
b = (c >> 4) & 0xF;
out = (r << 8) | (g << 4) | b;
break;
case DirectGraphics.TYPE_USHORT_4444_ARGB:
a=((c>>>28)&0xF); r=((c>>20)&0xF); g=((c>>12)&0xF); b=((c>>4)&0xF);
out=(a<<12)|(r<<8)|(g<<4)|b;
a = (c >>> 28) & 0xF;
r = (c >> 20) & 0xF;
g = (c >> 12) & 0xF;
b = (c >> 4) & 0xF;
out = (a << 12) | (r << 8) | (g << 4) | b;
break;
case DirectGraphics.TYPE_USHORT_555_RGB:
r=((c>>19)&0x1F); g=((c>>11)&0x1F); b=((c>>3)&0x1F);
out=(r<<10)|(g<<5)|b;
r = (c >> 19) & 0x1F;
g = (c >> 11) & 0x1F;
b = (c >> 3) & 0x1F;
out = (r << 10) | (g << 5) | b;
break;
case DirectGraphics.TYPE_USHORT_565_RGB:
r=((c>>19)&0x1F); g=((c>>10)&0x3F); b=((c>>3)&0x1F);
out=(r<<11)|(g<<5)|b;
r = (c >> 19) & 0x1F;
g = (c >> 10) & 0x3F;
b = (c >> 3) & 0x1F;
out = (r << 11) | (g << 5) | b;
break;
default:
throw new IllegalArgumentException("Unsupported format: " + format);
}
return (short)out;
return (short) out;
}

private static final BufferedImage manipulateImage(final BufferedImage image, final int manipulation)
Expand Down
30 changes: 27 additions & 3 deletions src/org/recompile/mobile/PlatformImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ public PlatformImage(int Width, int Height)
gc.fillRect(0, 0, width, height);
gc.setColor(0x000000);

isMutable = true;

platformImage = this;
}

public PlatformImage(int Width, int Height, int ARGBcolor)
{
canvas = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_ARGB);
// Create blank Image
width = Width;
height = Height;

createGraphics();

gc.setARGBColor(ARGBcolor);
gc.fillRect(0, 0, width, height);
gc.setColor(0x000000);

isMutable = true;

platformImage = this;
}

Expand Down Expand Up @@ -163,6 +183,8 @@ public PlatformImage(byte[] imageData, int imageOffset, int imageLength)

gc.drawImage2(temp, 0, 0);

isMutable = true;

platformImage = this;
}

Expand Down Expand Up @@ -192,6 +214,8 @@ public PlatformImage(int[] rgb, int Width, int Height, boolean processAlpha)

gc.drawRGB(rgb, 0, width, 0, 0, width, height, true);

isMutable = true;

platformImage = this;
}

Expand All @@ -213,12 +237,14 @@ public PlatformImage(Image image, int x, int y, int Width, int Height, int trans
System.arraycopy(sourceData, sourceRow, subData, subRow, Math.min(Width, image.platformImage.canvas.getWidth() - x));
}

canvas = transformImage(sub, transform);;
canvas = transformImage(sub, transform);

createGraphics();

width = (int) canvas.getWidth();
height = (int) canvas.getHeight();

this.isMutable = true;

platformImage = this;
}
Expand Down Expand Up @@ -276,8 +302,6 @@ public void setPixel(int x, int y, int color)

public boolean isMutable() { return isMutable; }

public void setMutable(boolean mutable) { isMutable = mutable; }

public static final BufferedImage transformImage(final BufferedImage image, final int transform)
{
// Return early if no transform is specified.
Expand Down

0 comments on commit 20fb8b7

Please sign in to comment.