Results 1 to 26 of 26

Thread: Bitmap in hMemDC [RESOLVED]

  1. #1

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46

    Bitmap in hMemDC [RESOLVED]

    Bitmap in hMemDC

    Hello again everyone,

    I have the following situation and am wondering if any of you clever people would be able to help me resolve it (I know CornedBee has been very helpful in the past).

    I have managed to place a bitmap within a hMemDC, only I would like to convert this bitmap to a much smaller image format without saving it so maybe placing it into another hMemdc. From reading various threads on this forum I know that it is fairly difficult to convert it to a JPEG without using a .dll which I do not mind (as long as they are free) using but most of these appear to require the image to be saved to disk rather than simply placing it into another hMemDC. I am also not really bothered as to what image type I convert it to as long as the size of the image is at least halved (not the actual dimensions of the picture).

    I would appreciate any help in this matter, as it is now driving me mad!

    Thanks in advance,
    Last edited by ISquishWorms; Nov 9th, 2002 at 07:29 AM.
    ISquishWorms

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    But then it wouldn't be a memory DC. When you store them in memory, they *must* be uncompressed and in full display format.

    Size is only really relevant when you save it anyway. I can't see why you want to do this here.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    Hi Parksie,

    Thanks for your quick reply. Maybe I should have said that I have an HBITMAP stored in memory, and I wish to convert this into a alternative smaller format within memory rather than having to save it. I know this is possible as I have managed this in Delphi, but now wish to do this in C as I prefer it to Delphi.

    Thanks,

    ISquishWorms
    ISquishWorms

  4. #4
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    I wouldn't recommend it. JPEG decoding is not fast enough for real-time display onscreen, so you'd end up trading memory for CPU time.

    Why is it so important?
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  5. #5

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    Parksie talk about quick, how quick was that reply I was only editing my responce to your first reply to find that your had already replied my second .

    It does not have to be in JPEG format (just a format with a fairly good compression ratio) and I am not trying to decode it I would like to encode it into an alternative format within memory. There must be a dll (free preferably) out there that will allow me to do this I really don't want to have to use Delphi for a solution but guess if I have to then so be it.
    ISquishWorms

  6. #6
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    If I'm here I'm usually fairly fast

    So you just want to store a compressed version in memory somewhere, that can me decompressed in non-real-time once you need it real-time, right?

    You need to be *very* careful because with lossy compression you'll cause lots of problems with the two pictures becoming inconsistent, and progressing to severe data loss.

    You could try using zlib, that could help, although you wouldn't get the compression rates of JPEG, it solves the loss problem.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  7. #7

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    Parksie, I am going to start calling your the bullet as your so fast to reply.

    Yes that is exactly what I would like to achieve, would this zlib allow me to hold my image in memory. Sorry but I am not familiar with zlib do you have an examples or info? Is this a picture format or simply a compression routine? Typically what compression ratios will this allow me to achive?

    Thanks for all your help on this matter so far and of course your speedy replies.
    ISquishWorms

  8. #8
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    ZLib is merely a compression format, the same as used in ZIP files, GZip, PDF, TIFF, etc.

    Look on google for the latest location of the website

    It uses a sliding-window algorithm, and normally gets much better results on text (you can get them down to about 5 to 10 percent size) than continuous-tone images such as photos (perhaps about 70% or so). Cartoon style images can get about 50% or so.

    What type of images are they? You might do better with some kind of RLE method. Dunno, don't have a copy of Windows to test this on
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  9. #9

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    Parksie,

    You don't have a copy of Windows? I take it that you do your programming on a different OS like Linux then (maybe).

    They are just fairly large 24bit bitmaps, some of the ones that I will be working with are currently 2meg in size. Thanks for the info on zlib I am off to try and find their website to ascertain what is required and what can be achieved using this method.

    In the meantime what is this RLE method that you mentioned sounds interesting? Do your have any examples or know where I might find some?

    Thanks once again for the replies and the time your taking in trying to help me find a solution.
    ISquishWorms

  10. #10
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Last year I was doing it professionally on multiprocessor SGI systems running Irix (Unix variant), and decided I preferred it, so I made the move to GNU/Linux on my personal machine. Already had it on my router (uptime since last power cut below ) so I knew a little bit about it.

    Aaaaanyway.

    RLE == Run Length Encoding. Only works well for cartoon style images with large blocks of the same colour, because rather than going, "red red red red green green purple blue blue blue blue blue blue blue" you can go "4 red 2 green purple 7 blue".

    Almost unusable for photographic or otherwise continuous-tone images though.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  11. #11

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    The pictures that I am dealing with are not cartoons so I guess that I should forget the RLE method for this purpose then, although it is possible that some of them (not all) may have fairly large colour blocks that are the same. Considering that not all of the pictures will possibly have these large blocks of colour I guess I should go with the average picture type and try and use an alternative method of compressing them for now (does this sound reasonable?). Would the RLE method work better than the zlib method when the pictures have large colour blocks or would zlib do just as good a job?

    I have been to the zlib website and downloaded the source, although have not yet looked at it. I take it I will need to compile the source myself? Are there any good examples of using zlib?

    Thanks, Parksie I don’t think I have ever had my forum threads replied too as quickly as you have this one.
    ISquishWorms

  12. #12
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Was not around for a while...

    RLE will do better when there are large blocks of the same color (actually they don't need to be blocks, horizontal lines are just as good because of the way RLE works). It can also be decompressed nearly in real-time (depends on CPU and memory speed, mainly memory).
    But since you probably don't know what to expect I recommend zlib.

    But you should ask yourself: is 30% memory saving worth the loss of speed? If you tell us what you want to do exactly, we might help you with that decision.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  13. #13

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    Hi CornedBee, it's nice to see your back. I did notice that you had not been around as much as usual, been anywhere nice? I was getting a little worried as I normally count on you to provide me with reasonable answers to my questions.

    I think I may give this RLE method a go if only to learn from it as it sounds interesting especially as both you and Parksie (who I consider to be both experts when it comes to C++) mentioned it. Do you have any good examples or know where I might find some that will get me started?

    I have not decided against using zlib it's just that I would like to experiment using RLE as it is a new concept to me. I may afterwards revert back to trying to use zlib.

    Thanks for the reply and advice CornedBee,
    ISquishWorms

  14. #14
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    RLE is a very old technique, but the implementation always varies a little. Maybe you know the pcx bitmap format, it uses RLE. I think it might be a good format to use. You can get information on it on wotsit.org.

    I have thought of an RLE format to use for pure black/white images (RLE really rocks there). It goes like this: every pixel is two bits. The first is the pixel value, the second is 0 if it's a single pixel or 1 if it's repeated. If it is, the next n bits are the repeat count (not necessarily byte-aligned, and I have to think of a good value for n, must be divisible by 2).

    Of course this only works for black/white images.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  15. #15

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    CornedBee, thanks for the insight I never knew that the pcx format used RLE, mind you I did not know about RLE until recently. I will check out that website that you mentioned and have a look.

    My first hurdle in trying to implement this method is that I need to know how to access the individual bytes of the HBITMAP that I store in memory and I am unsure how to do this. I did some of my own investigation into the RLE method as well last night and found the following code (it is not my code), does this code look like a good starting point for what I am trying to achieve? Are there any obvious mistakes in the code (I could not spot any, but as you have vastly more experience in C++ you may)? Your black and white method sounds interesting too, although my pictures are currently in colour I was considering maybe converting them to greyscale, but again I am a little unsure on how I would do this.


    RLE Compression / Decompression, by William Swanson:
    Code:
    /******************************************************************************
     * LoadRLE / SaveRLE - Load and save binary data using RLE compression.
     *	Run-length tokens have a set MSB, while data tokens have a cleared
     *	MSB. The value of the token's remaining bits plus one indicates the
     *	length of the block. The minimum run length is three bytes, while
     *	the maximum is 128.
     *
     *	data - Array holding data to load or save.
     *	size - Size of the data array.
     *	file - The file pointer to use.
     *	return - Total number of bytes read from or written to data[].
     */
    
    size_t LoadRLE (unsigned char data[], size_t size, FILE *file)
    {
    	unsigned char token;
    	unsigned int length;
    	size_t total = 0;
    
    	while(size && fread(&token, 1, 1, file))
    	{
    		length = (token & ~0x80) + 1;
    		if (length > size)
    		{
    			return total;
    		}
    		if(token & 0x80)
    		{
    			if(!fread(&token, 1, 1, file))
    			{
    				return total;
    			}
    			memset(data, token, length);
    		}
    		else
    		{
    			if(fread(data, 1, length, file) != length)
    			{
    				return total;
    			}
    		}
    		data += length, size -= length, total += length;
    	}
    	return total;
    }
    
    /*************************************/
    
    size_t SaveRLE (unsigned char data[], size_t size, FILE *file)
    {
    	unsigned char token;
    	unsigned int i;
    	size_t total = 0;
    
    	while(size)
    	{
    		/*This loop identifies blocks of repeating data:*/
    		i = 2;
    		while(i < size && i < 128 &&
    			data[i] == data[i - 1] && data[i - 1] == data[i - 2])
    			i++;
    			/*If repeating data was found, save it:*/
    			if(i > 2)
    			{
    				token = i - 1 | 0x80;
    				if(!fwrite(&token, 1, 1, file))
    					return total;
    				if(!fwrite(data, 1, 1, file))
    					return total;
    				data += i, size -= i, total += i;
    			}
    		/*This loop identifies blocks of non-repeating data:*/
    		i = 0;
    		while(i < size && i < 128 && (i + 2 > size ? 1 :
    			data[i] != data[i + 1] || data[i + 1] != data[i + 2]))
    			i++;
    		/*If non-repeating data was found, save it:*/
    		if(i){
    			token = i - 1;
    			if(!fwrite(&token, 1, 1, file))
    				return total;
    			if(fwrite(data, 1, i, file) != i)
    				return total;
    			data += i, size -= i, total += i;
    		}
    	}
    
    	return total;
    }
    Any advice CornedBee will as always be gratefully appreciated, thanks in advance.
    Last edited by ISquishWorms; Nov 8th, 2002 at 08:20 AM.
    ISquishWorms

  16. #16
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Looks ok, but I'm not looking at it in great detail.

    Beware if you want to change the pixel values of a HBITMAP, you'll get weird effects and probably no memory savings.
    It's better to save the pixel data in your own memory location and create a HBITMAP every time you need it, then decompress into it, blit to the screen and destroy the bitmap.

    greyscale conversion goes like this:
    byte r = redvalueofpixel(pixel);
    byte g = greenvalueofpixel(pixel);
    byte b = bluevalueofpixel(pixel);
    float gray = 0.3333f * r + 0.5f * g + 0.1111f * b;
    r = g = b = (byte)gray;
    setpixelrgb(pixel, r, g, b);

    Do this for every pixel. The numbers are scaling factors, because the human eye doesn't weigh all colors the same.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  17. #17
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    On an unrelated question: which is American English and which is Bristish English:
    grey
    gray
    ?
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  18. #18

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    Both are valid in UK English but mean something different.

    UK English Definitions:

    Grey: intermediate between black and white, coloured like ashes or lead.

    Gray: (Phys.) unit of absorbed radiation dose, corresp. to one joule per kilogram.

    I am from the uk by the way.
    ISquishWorms

  19. #19

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    Beware if you want to change the pixel values of a HBITMAP, you'll get weird effects and probably no memory savings. It's better to save the pixel data in your own memory location and create a HBITMAP every time you need it, then decompress into it, blit to the screen and destroy the bitmap.
    I am not sure I understand what you are saying. I currently have my HBITMAP in memory and wish to compress it using a compression routine, but I am a little confused now on how to do this. Do I need to address each pixel and compress it or convert each pixel into a byte? Why would I get strange effects? I thought I had started to understand what it is I need to do but now I am unsure again ahhhh.

    Thanks for any further explanation(s) that you maybe able to provide to help me understand exactly what process and approach I need to take with this.
    ISquishWorms

  20. #20
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    You can get access to the pixel data using GetObject.

    But when you compress the data and then do
    SelectObject(hdc, hbmCompressed);
    the result won't be what you expect.

    So I'd rather have a BYTE array with the compressed data and uncompress it every time you draw, then remove the uncompressed copy.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  21. #21

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    OK thanks, I think I understand now but that does mean that potentially the array could be quite large. Is there a limit on how big an array can be? How would I declare such a large array? I have also been investigating the Huffman’s method of compression which do you think might give me the best results. Is the Huffman compression better than RLE?

    Sorry to keep bothering you with all these questions.

    Thanks again for the time your taking to help me!!
    ISquishWorms

  22. #22
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Don't know what Huffman's compression is. Isn't it the compression algorithm underlying JPEG? If so, it's lossy.

    If windows can internally store an array large enough to hold a complete bitmap then why shouldn't you?
    Don't declare it on the stack, use new, malloc, HeapAlloc or (best for really large arrays) VirtualAlloc.
    For stack arrays the size limit is very low: the whole stack can only be 1 MB large, so a 500k array is very dangerous.
    Heap arrays I think are bound to the page size, but I might be wrong. Arrays allocated with VirtualAlloc are only bound by available memory, both physical and virtual.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  23. #23

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    If you’re not sure if Huffman's compression algorithm underlies the JPEG compression how do you expect me to know? I don’t consider my knowledge to be as extensive as yours.

    From your previous post I think that VirtualAlloc sounds like the method that I should be using just one question how (never used it)? It would be best I assume to only allocate as much space as I need so taking this in to consideration I guess that I need to somehow make this dynamic.

    I promise you that this will be the last question I ask of you for now as I have taken far too much of your time already CornedBee. I will mark this thread as being resolved after your next reply and go and try some of your suggestions out, although I may be back to ask you for more advice if not on this topic I am sure on others.

    Thanks both to CornedBee and Parksie for your contributions and help that you have both provided me in trying to solve this problem.
    ISquishWorms

  24. #24
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Huffman coding is partially used in ZIP compression, so it's not lossy. It is also used in JPEG, I think (it's a very versatile technique using trees).
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  25. #25
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    The simplest usage of VirtualAlloc is
    LPVOID lpMem = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    size should be a multiple of the system page size for maximum efficiency (it's actually automatically rounded up) which can be obtained with GetSystemInfo, where it is the dwPageSize member of the SYSTEM_INFO structure.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  26. #26

    Thread Starter
    Member
    Join Date
    Jun 2002
    Posts
    46
    OK thanks, you both have been extremely helpful!

    I will mark this thread as resolved now as it is time that I actually go and try and put some of what I have learnt in to practice and I have taken too much of your time already. I may be back to ask more questions if things don’t seem to be working out too well, if that is ok. So I guess here comes the tricky part actually programming the routines.

    Cya for now
    ISquishWorms

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width