Putting things into perspective

You guys do understand that modifying the image is pointless, right? It’s just a visual representation of a ZIP data stream. Any attempts to modify it would corrupt the JAR file, guaranteed.

Creating a program to reverse the process would work for the black and white images. (Not that I can figure out anything useful for it.) However, the conversion between RGB and YUV is fraught with rounding errors and would probably screw up the data.

wow this is amazing now i can look at the 4k games in a totally different way ;D

making a height map out of them would also be cool, as in 3d terrain

hint* please someone do that ;D *hint

[quote=“jbanes,post:21,topic:26221”]
I don’t think any colour space conversion applies in this case. PNG is a lossless format and it typically uses RGB.

I believe jbanes is refering to his own code for generating the colorized versions.


int Y = ((data & 0xE0) >> 6);
            int U = ((data & 0x1C) >> 3);
            int V = (data & 0x03);

            double R = Math.abs(Y + 1.403 * V);
            double G = Math.abs(Y - 0.344 * U - 0.714 * V);
            double B = Math.abs(Y + 1.770 * U);

There is certainly rounding error in there =)

I do know that it is pointless, and I realized it’d work better with b&w, that’s why I suggested using those. I just tnink it’d be interesting to see, letting you convert to images and back (here’s my java source, encrypted. Decompile this: (sending png)). :>

and I realized it’d work better with b&w

My ARGB version is just fine. Each pixel contains 4 bytes of information and its lossless. You can also embedd some meta information in png files. So, you could write some loader which hooks such a png into the classpath and runs the main class specified in the tEXT chunk.

Nice to see my entry (Sokoban4k) used for something! :wink: And this is a crazy idea! :slight_smile:

There had better be some serious geek cred in this. Here you go:

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.jar.*;
import java.util.zip.*;

import javax.imageio.*;

public class ImageRunner4K
{
    public static void main(String[] args) throws Exception
    {
        int[] buffer = new int[4096];
        byte[] array = new byte[4096];

        BufferedImage image;
        ZipInputStream jarin;
        ZipOutputStream jarout;
        ZipEntry entry;

        int data;
        int index;

        if(args.length < 1)
        {
            System.out.println("Usage: java ImageRunner4K <input>\n\nDo not pass the PNG extension.");
            return;
        }

        image = ImageIO.read(new File(args[0]+".png"));
        image.getRGB(0, 0, 64, 64, buffer, 0, 64);

        for(int i=0; i<buffer.length; i++) array[i] |= (buffer[i] & 0xFF);

        jarin = new ZipInputStream(new ByteArrayInputStream(array));
        jarout = new ZipOutputStream(new FileOutputStream(args[0]+".jar"));
	

        while(jarin.available() > 0)
        {
            index = 0;
            entry = jarin.getNextEntry();

            if(entry == null) break;

            array = new byte[(int)entry.getSize()];

            while(index < array.length) index += jarin.read(array, index, array.length-index);

            jarout.putNextEntry(new ZipEntry(entry.getName()));
            jarout.write(array, 0, array.length);
            jarout.closeEntry();
        }

        jarout.close();
        jarin.close();

        URLClassLoader loader = new URLClassLoader(new URL[]{new File(args[0]+".jar").toURL()});
        Manifest manifest = new Manifest(loader.findResource("META-INF/MANIFEST.MF").openStream());
        Attributes attributes = manifest.getMainAttributes();
        String className = attributes.getValue("Main-Class");

        Class gameClass = loader.loadClass(className);
        Method method = gameClass.getMethod("main", new Class[]{String[].class});

        method.invoke(null, new Object[]{new String[0]});
    }
}

It only works on the Grayscale images. You use it by running "java ImageRunner4K " where “name” is the name of the PNG file without the extension. Don’t run this in the same directory where you have your master JAR files or you may be in for a nasty surprise.

Edit: There are test files you can use in this post.

I’m not worthy! You are awesome!!

Awesome. You have all the cred you want :smiley:

EDIT: Can’t get it to work though. Crashes with:

Exception in thread "main" java.lang.NegativeArraySizeException
        at ImageRunner4K.main(ImageRunner4K.java:48)

[quote=“Morre,post:30,topic:26221”]
Can you attach the image you’re using to a post? (Click on “Additional Options” below the text area to find the upload options.)

Edit: Never mind. I’ve reproduced it with IceJump4K. It looks like the size data is being stored improperly. I’ll try to find a workaround.

Edit 2: Okay, good news/bad news. I can work around the problem with the ZIP format, but you didn’t mark your class file as public.(Why not?) I’m going to have to muck with the security manager to see if I can forcably grant access.

I’m still working on the security issue (my memory is a bit rusty on working with Policies), but in the meantime, here’s a version that handles badly formed ZIP files:

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.jar.*;
import java.util.zip.*;

import javax.imageio.*;

public class ImageRunner4K
{
    public static void main(String[] args) throws Exception
    {
        int[] buffer = new int[4096];
        byte[] array = new byte[4096];

        BufferedImage image;
        ZipInputStream jarin;
        ZipOutputStream jarout;
        ZipEntry entry;

        int data;
        int index;

        if(args.length < 1)
        {
            System.out.println("Usage: java ImageRunner4K <input>\n\nDo not pass the PNG extension.");
            return;
        }

        image = ImageIO.read(new File(args[0]+".png"));
        image.getRGB(0, 0, 64, 64, buffer, 0, 64);

        for(int i=0; i<buffer.length; i++) array[i] |= (buffer[i] & 0xFF);

        jarin = new ZipInputStream(new ByteArrayInputStream(array));
        jarout = new ZipOutputStream(new FileOutputStream(args[0]+".jar"));
        entry = jarin.getNextEntry();

        while(jarin.available() > 0)
        {
            index = 0;

            if(entry == null) break;

            jarout.putNextEntry(new ZipEntry(entry.getName()));

            while((data = jarin.read()) >= 0) 
            {
                jarout.write(data);
                index++;
            }

            jarout.closeEntry();

            entry = jarin.getNextEntry();
        }

        jarout.close();
        jarin.close();

        URLClassLoader loader = new URLClassLoader(new URL[]{new File(args[0]+".jar").toURL()});
        Manifest manifest = new Manifest(loader.findResource("META-INF/MANIFEST.MF").openStream());
        Attributes attributes = manifest.getMainAttributes();
        String className = attributes.getValue("Main-Class");

        Class gameClass = loader.loadClass(className);
        Method method = gameClass.getMethod("main", new Class[]{String[].class});

        method.setAccessible(true);
        method.invoke(null, new Object[]{new String[0]});
    }
}

How about a 3D 4k game that uses it’s own jar as a heightmap. Naw, it’s just too silly.

hahaha

That IS pretty silly. ;D

lol thats a nice idea :slight_smile:

Ok, the security issue is fixed. I’ve patched the code in my post above (added “method.setAccessible(true);”) and that grants access to the otherwise protected class.

Youd have to code for heightmap beutification, as well as the 4k limit, as well as performance, as well as multiplatform! Craaazy!

* darkprophet goes off to try!