Scaling down the no. of bitsÖ

Moderator
Posts: 698
Joined: 2002.04
Post: #1
Perhaps an odd query, but any suggestions as to a good technique for scaling down the no. of bits used to hold the RGB components of a pixel of an image? The required no of bits is 5 (range 1 - 0x5); currently the no. of bits is 16 (range 1 - 0x10000); yes, ouch, the term 'lossless' isn't going to be applied here Blink

The current technique I'm employing isÖ
[sourcecode]
#define BGR( b, g, r ) (( b << 10 ) + ( g << 5 ) + r )
#define RGB( r, g, b ) BGR( b, g, r )
[Ö]
percent_pixel_components[ r ] = ((pixel_components[ r ] / ( pow( 2, 16 ) - 1 )) * 100 );
pixel_components[ r ] = ( percent_pixel_components[ r ] * (( pow( 2, 5 ) - 1 ) / 100 ));
[Ö]
pixel = RGB( pixel_components[ r ], pixel_components[ g ], pixel_components[ b ] );
[/sourcecode]
Öwhich has the unfortunate effect of, well, it's best described with an image (although to be truthful, I'm quite surprised this technique resulted in an even vaguely recognisable image at all.)

The inputÖ
[Image: pre.png]
The outputÖ
[Image: post.png]

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Moderator
Posts: 698
Joined: 2002.04
Post: #2
[Later : messed about with the code, which fixed the problems with the colour, but I'm still at a loss as to the cause of the 'slant' problem.
The image which results from the updated codeÖ
[Image: other.png]
]

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
Why 5 bits? Surely you can get away with 8!!

Probably the best thing to do is to create a 32-entry CLUT per image, and pixel values in the resulting image are table indices.

If you want to do true-color, try 2-2-1 and 1-3-1:

Code:
unsigned char RGB888ToRGB221(unsigned char red, unsigned char green, unsigned char blue)
{
    return ((red & 0xc0) >> 3) | ((green & 0xc0) >> 5) | ((blue & 0x80) >> 7);
}

unsigned char RGB888ToRGB131(unsigned char red, unsigned char green, unsigned char blue)
{
    return ((red & 0x80) >> 3) | ((green & 0xe0) >> 4) | ((blue & 0x80) >> 7);
}

I'd guess the slant is to do somehow with image packing or rowbytes or something. 5 bits doesn't pack very nicely into bytes...
Quote this message in a reply
Moderator
Posts: 698
Joined: 2002.04
Post: #4
The 5bit per RGB component limit isn't something I've chosen; I'm trying to code an image converter for the OS X terminal to help with GBA dev, comparable to those available for DOSÖ the images of the output are screenshots taken in Boycott Advance.

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
w_reade
Unregistered
 
Post: #5
Time to break out those bitshift operators, methinks... you'll need to work out 8 pixels at once and put the result into 5 bytes, so that it's all contiguous. Messy but sort-of fun. Must sleep, complain if it's gibberish...
Quote this message in a reply
Member
Posts: 177
Joined: 2002.08
Post: #6
As for the slant, you are probably failing to consider the true length of each line in the image, which is not always equal to width * bytes per pixel.
Quote this message in a reply
Member
Posts: 269
Joined: 2005.04
Post: #7
As other people have said, you're going past the true width of the image on each line, which results in that exact slant that you're seeing (I saw the same thing months ago when I wrote my own draw-direct-to-screen function).

Basically you take the number of pixels in a row, and you left shift (<<) it by (imageDepth << 4) (or 0 for 8-bit, 1 for 16-bit, 2 for 32-bit). And to get the proper pixel to start at you take the image's frameBaseAddr + y (in this case 0, since you're doing the whole image) + (x for 8-bit, x+x for 16-bit, x<<2 for 32-bit)

If that makes no sense or it does and it doesn't work, try posting the complete code for the function.
Quote this message in a reply
Moderator
Posts: 698
Joined: 2002.04
Post: #8
Thanks for the suggestions, but I've found the cause of the problem - the initialisation value of vars in METAL (which I'd used to prep the images for furter conversion) - anyways, I'd been unknowingly preping an unessarry 0xa0 * 0x10 bits worth of pixels, which caused the slant as the unessarry pixels were drawn, 0x10bits worth per line.

The (almost fixed - I need to shift the image a pixel to the right to stop random data deing drawn) looks like thisÖ
[Image: almost_fixed.png]
Anyways, if anybody wants a copy of the app for some strange reason, just email.

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  scaling of textures WhatMeWorry 1 2,193 Jul 30, 2005 03:41 AM
Last Post: NCarter
  Scaling to different Resolutions blobbo 10 4,580 Apr 22, 2005 05:48 PM
Last Post: NCarter