I'm currently working on an algorithm that, similar to PNG-related formats, is lossless when a picture is rendered. I will start by explaining the format of a normal 24-bit bitmap image, and how one can quickly access the actual picture data and dimensions, and then go into depth on how far I've decided on how compression routines will work.



On-Computer Absorption, Compression, and Padding (ACP phase)

In a bitmap file, the chunks of data we are most concerned with are, and how large the values are:

- The offset from the beginning of the file the raw image data is documented 0x0A bytes from the beginning of the file (32bit)
- The size of the DIB header after the normal BMP header's size (non-inclusive) is 0x0E bytes from the beginning of the file (32bit)
- Width of bitmap is 0x12 bytes from beginning (32bit)
- Height of bitmap is 0x16 bytes from the beginning (32bit)
- We can check to see if input file is 24bit encoded by checking to see if byte 0x1C == 0x1800 (16bit)
- Size of raw pixel data is in 0x22 (this includes 4-byte alignment pads)

some notes:

- The format of a WINDOWSDIB bitmap file is in the order BMP_HEADER, DIB_HEADER, and RAWDATA. The BMP_HEADER and DIB_HEADER always start in static locations
- The end of the file can be marked as (beginning + *(beginning+0x0A) + *(beginning+0x22))
- each 'row' of pixels MUST be a multiple of 4, so if the lines are not aligned to that, there will be extra padding bytes with the value 0x00 inserted


This is good information for simply scanning a bitmap file for the data within, and I almost have a Ruby script up and working that will absorb the entire bitmap's raw data minus the paddings into a array from which it can be loaded into an ACPNG file format (Ashbad Compressed Prizm Networks Graphic file -- the file format pioneer has the first pick for the name Very Happy) and then padded into a Prizm-C compatible 'const char NAME[] = {' format that can be inserted into a source file as regular picture data.



Actual Compression Concerns and Ideals

The style of compression planned for uses a lossless Pixel-Prediction algorithm that I almost have perfected for theoretical decently fast rendering and high compression rates (which can only be estimated, and not be said for sure, until I go into intensive testing mode). This method is very similar to what low-standard PNG images use, and can be summed up by this ripped picture from wikipedia -- the pixel X's value is predicted by the values of A,B,C, and D:

Cemetech doesn't support .svg files, so view it at this URL if you want: http://upload.wikimedia.org/wikipedia/commons/3/39/Pixel-prediction.svg

Another feature is palette indexing, for pictures with or less than 256 colors. This is tightly wrapped indexing, so if a picture has something like 126 colors, it would be based on a 7 bit palette with 126 entries. Or, a better example (let's use a value 127 < # < 255 for an 8 bit example) a picture with 192 colors would have 8 bit indexing, but would still be more compressed than a picture with 250 colors because it would support only 192 colors. I may have it later so you can still specify indexing for #ofcolors with 9-11 bit values, but the compression with this technique would be drastically less obvious, rising sub-exponentially at each bit level added.

The point of all of these measures (and a few I didn't mention yet) is to get an image file as small as technologically possible without any color loss -- that's why PNG-based compressions are generally more of a pain to write than 92% reducing JPEG compressions Razz If you want an educated guess on how compressed a picture would be with this, I'll take Kerm's obliter8 title screen with a ~160K data size he regularly publically laments about. I assume from looking at the image itself it contains around 200-250 colors total, which with a indexing table would drop it to 80K instantly, no losses. The prediction method is much harder to predict to the many factors that relate output size and input size, such as size, bit depth and (surprisingly) width and height. Though, making a good guess, it'll knock off at least an additional 30% from where we were, bringing his title screen down to a more reasonable ~60K size, knocking already 100K of the top.

However, if I use advanced deflation and line-based predictions, along with other features I haven't looked into much yet, it could drop to ~35K. Yay Kerm's title screen! Smile



Prizm-C routine to convert ACPNG data to nomal bitmap format

I haven't worked on it nearly as much, but the actual routine that renders ACPNG data will function with the following format, subject to change:


Code:
unsigned char Render_ACPNG_Data(void*datapointer, short x, short y, char mode, void*additional_args = 0);


inputs: pointer to ACPNG data, x position to render to in VRAM, y position to render to in VRAM, 8 bit value mode for how to render, optional pointer to additional arguments to communicate with the decompressor directly (mostly for debugging and possibly for getting info on data and such)

outputs: obvious.


Quite possible Specifications of the actual Prizm-C routine:

- estimated 1-5K function code size
- estimated 6-8 times slower rendering than normal graphical data
- estimated 1-24 hours Kerm will be happy I made a routine that will lower his title screen size

besides the silly last one, the specs are actual estimates I theorize will be a result, and will most likely not be subject to change.


Questions, Comments, "I WANNA HELP", etc.

feel free to post anything described in the sub-title's below or email me at a s h b a d . a l v i n @ g m a i l . c o m (remove spaces obviously Razz AND DO NOT REPEAT IT HERE WITHOUT SPACES.)

~Ashbad
Can you estimate the compression factor on various images? And do you mean 1-5K LoC, or bytes of assembled code? I hate to be a skeptic, but I'll believe it when I see it. Wink
Doing a quick bit of math, a 35kb from 160 kb puts it at the lower end of PNG efficiency, but slightly higher than GIF's.
Qwerty.55 wrote:
Doing a quick bit of math, a 35kb from 160 kb puts it at the lower end of PNG efficiency, but slightly higher than GIF's.
I find that slightly suspicious, so I'll be excited to see this come to fruition.
KermMartian wrote:
Qwerty.55 wrote:
Doing a quick bit of math, a 35kb from 160 kb puts it at the lower end of PNG efficiency, but slightly higher than GIF's.
I find that slightly suspicious, so I'll be excited to see this come to fruition.


Qwerty is actually right about that. It could even be possible using normal PNG methods to lower it much more than that, but you have to admit 35K is already pretty decent, since .gif will slightly lower your quality, and this is completely lossless. If i did use normal techniques, it woule be much slower to render things on the prizm -- and i would think you wouldn't want to wait 2-3 seconds for your title screen to load.

1-5K for assembled code is actually a pretty decent estimate, Kerm. Though, when I think deeper, it'll be closing in on the 4-5K range. I'm getting this number based on how I'm doing compression, and looking at this compared to an early PNG rendering script in Java (the C++ ones are very hard to follow due to intense optimizations). The Java one is around 7K, and with all of the overhead cut out and with the fact that C will allow for much better optimization, I arrived at 4-5K
Fair enough. Would you care to post the exact algorithm you'll be using or point me to it in the Wikipedia article, or is it still a work in progress?
KermMartian wrote:
Fair enough. Would you care to post the exact algorithm you'll be using or point me to it in the Wikipedia article, or is it still a work in progress?


Unfortunately, it still is a work in progress Razz however, I can point you to wikipedia/other articles I used to help me find more specific sources:

http://en.wikipedia.org/wiki/Bitmap_file_format
http://en.wikipedia.org/wiki/PNG_file_format
http://www.dvd-hq.info/data_compression_1.php
http://en.wikipedia.org/wiki/Interlacing_(bitmaps)
http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Image_decoding
http://optipng.sourceforge.net/pngtech/optipng.html

EDIT: somehow netbeans didn't save my latest Ruby file, so it's mostly gone :/ I'll try to remake it today.
I'm familiar with all those algorithms, but you mentioned a very specific lossless pixel-prediction concept, so I thought that perhaps you had something more solid, especially since you cited compression ratio numbers. Smile
I have many things completely confirmed on how I'm going to be doing this, believe me, I just really need to focus on actually getting some code done (hopefully 90% of the computer script part by tonight) so I haven't really gotten into depth much with explaining Sad sorry.

However, the Ruby code I'll be sharing later on this week will answer all questions about what compression techniques I'm using Wink

EDIT:

I've now recovered most of the Ruby file progress, and optimized the absorption code with a few new methods I recently discovered:


Code:
class BitmapFile
  directory = nil
  openedfile = nil
  EXTENSION = "bmp"
  def initialize(directory)
    @directory = directory.chomp.to_s
    if @directory.rpartition(".")[2] != EXTENSION
      puts 'Exiting -- not a bitmap!!'
      exit
    end
  end
  def getdir
    return @directory
  end
  def openfile
    @openedfile = File.new(@directory, "r")
  end
  def closefile
    @openedfile.close
  end
  def getsize
    return File.size(@directory)
  end

end

currentfile = BitmapFile.new("C:\\Users\\Adam\\Desktop\\kitty.bmp")
currentfile.openfile
object = 255
absorbed_file = Array.new(currentfile.getsize, object)
currentfile.getdir.each_byte {|byte|
    absorbed_file[byte] = byte
}
currentfile.closefile

puts 'Currently chosen file  :--  ' << currentfile.getdir;puts
well, IRB was lying to me, it doesn't absorb anything. However, quite fixed up with this:


Code:
class BitmapFile
  directory = nil;openedfile = nil #non-standards
  EXTENSION = "bmp" #constants
  sizeoffile = nil #standards
  def initialize(directory)
    @directory = directory.chomp.to_s
    if @directory.rpartition(".")[2] != EXTENSION
      puts 'Exiting :-- not a bitmap!!';exit;end
    @sizeoffile = File.size? @directory
    if @sizeoffile == nil;puts 'Exiting :-- file doesn\'t exist!';exit;end
  end
  #non-implied get methods
  def getdir;return @directory;end
  def getbyte(specific_byte);return IO.read(@directory, 1, specific_byte);end
  def getsizeofile;return @sizeoffile;end


end


currentfile = BitmapFile.new("C:\\Users\\Adam\\Desktop\\kitty.bmp")
absorbed_file = Array.new(currentfile.getsizeofile) {|byte_index|
  byte_index = currentfile.getbyte(byte_index).bytes.to_a
}


puts 'Currently chosen file  :--  ' << currentfile.getdir
puts 'Size of Bitmap file    :--  ' << absorbed_file.length.to_s << " bytes\n"


now that it FINALLY works like it's supposed to, we're all good it seems for now. It puts me back a day, but oh well.
So far I'm seeing lots of file manipulation but not image manipulation. Smile I wait with baited breath.
KermMartian wrote:
So far I'm seeing lots of file manipulation but not image manipulation. Smile I wait with baited breath.


Well, I've never done anything with IOstreams or even files before, so the fact that I have it up is decent progress for me. All in good time, Kerm.
Ashbad wrote:
KermMartian wrote:
So far I'm seeing lots of file manipulation but not image manipulation. Smile I wait with baited breath.


Well, I've never done anything with IOstreams or even files before, so the fact that I have it up is decent progress for me. All in good time, Kerm.
Cool, then good for you for learning how to do it. I can't say I'm thrilled about your language choice, but I think shaun already harangued you about that, so moving on. Wink
KermMartian wrote:
Ashbad wrote:
KermMartian wrote:
So far I'm seeing lots of file manipulation but not image manipulation. Smile I wait with baited breath.


Well, I've never done anything with IOstreams or even files before, so the fact that I have it up is decent progress for me. All in good time, Kerm.
Cool, then good for you for learning how to do it. I can't say I'm thrilled about your language choice, but I think shaun already harangued you about that, so moving on. Wink


Thanks Smile it seemed like black magic before, but the Ruby Way of doing it with such good documentation finally helped me understand. Now that I have that down, from here won't be as bad Smile also, I don't merth actually 'harangued' about it himself, he might actually be the only one who didn't Laughing
Based on seeing what Ruby looks like, I think you'd find C# and/or Python fairly understandable, and I feel like people take those languages a bit more seriously. Anywho. I should mention that Tari is also working on an image compression/inflation program and function for the Prizms, if I understand correctly.
Ah, his will most likely be better. However, this can at the very least be good practice for me, no pain no gain when coding. The more applications you make, the more you go ProgrammingSkills++.

What I find as funny is how people here don't take Ruby seriously. The only really big downside of the language is speed, though that is can be an avoided issue if you use IronRuby or JRuby platforms (I use YARV for testing, it's ~10 times slower, but awesome for debugging stuff nice and quick overall). Other than that, sure it's a bit harder to get used to, but once you get used to it you feel nice and comfortable with it's design and it's actually quite enjoyable to program in.

However, the only opinions here I take seriously about Ruby are really yours, Merth's and a few others who may have or not have tried the language, but have knowledge in similar languages like Python and Perl (C# is somewhat similar, though I would more name it closer to Java). In the business world, Ruby isn't an uncommon language and many sites take advantage of the Ruby on Rails framework, as it provides the highly loose development of Ruby with a firm base for execution, and it does wonders to websites.

And as a fun fact, there are more blogs by people on their experience/comments on Ruby than most other languages, and is considered the 'Blog' language, or in other means the 'Relaxation' language Laughing

Well, long story short, I've tried C# and I don't like it much, though much better than Java in quite a few cases; and I think python isn't quite as enjoyable to program in.
The Ruby language feels like the bastard child of Python and Perl, but I love the Rails and ActiveRecord APIs. As a whole I think Python is a better language though.
Well, I respect your opinion, because opinions are a key part of life Smile

However, I still think Ruby as a language is slightly superior to Python from my working with it before. Again, opinions.
Ashbad wrote:
Well, I respect your opinion, because opinions are a key part of life Smile

However, I still think Ruby as a language is slightly superior to Python from my working with it before. Again, opinions.


List and Dict comprehensions Wink
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement