Thread: A strange problem with regions

  1. #1
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102

    A strange problem with regions

    Hi!

    I'm trying to loop through pixels of a bitmap, check for their RGB values and add to a region if they match with a specified color.

    Code:
    	for(WORD y=0; y<wBmpHeight; y++)
    	{
    		for(WORD x=0; x<wBmpWidth; x++)
    		{
    			for(std::map<char*, CMould>::iterator it=moulds.begin(); it!=moulds.end(); it++) //this map holds 26 different color values and region handles
    			{
    				if(RGB(pPixels[p+2], pPixels[p+1], pPixels[p]) == it->second.trnsphRGB)
    				{ //if the colors match
    					int iRes = CombineRgn(it->second.regionHandle, 
                                                                it->second.regionHandle, 
                                                                CreateRectRgn(x, y, x+1, y+1), RGN_XOR); //add this pixel to the region
    				}
    			}
    			p+=3;
    		}
    		itoa(y, pOut, 10); //just to display the current y line
    		SetWindowText(hwnd, pOut);
    	}
    All goes well and CombineRgn returns COMPLEXREGION (success) until line 138, pixel 514. The function returns ERROR on this and further pixels. I found out with GetLastError() that the error code is 6 (invalid handle). I don't get why it->second.regionHandle is invalid, because the debugger shows the exact same handle address for both- successful and unsuccessful calls to CombineRgn.

    The CMould class is nothing special, regionHandle is initialized in the constructor.

    Header:
    Code:
    #ifndef MOULD_H
    #define MOULD_H
    
    class CMould
    {
    public:
    	CMould(COLORREF color, char** shouts);
    	CMould(){}
    	HRGN regionHandle;
    	COLORREF trnsphRGB;
    	char** pShouts;
    };
    
    #endif
    CPP:
    Code:
    #include "stdafx.h"
    
    CMould::CMould(COLORREF color, char** shouts)
    {
    	trnsphRGB=color;
    	memcpy(pShouts, shouts, sizeof shouts);
    	regionHandle = CreateRectRgn(0, 0, 1, 1);
    }
    I can't think of what might be causing it.
    Thanks for any help.
    Last edited by Overlord; 05-09-2008 at 12:06 PM.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I suspect you are just creating a region too complicated for Windows to deal with.

  3. #3
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Regions are a screwy thing in the API, my friend. They are actually a very resource consuming object. Thus memory leaking is always lurking around the corner.

    Rasterization is a good way around this (in my experience). Instead of adding each pixel to your region at once, add code that does something like:

    Example:
    Code:
    // Sorry for not being up on my MFC... but you should be able to MFC-ify this.
    RECT line = {0,0,0,0};
    bool inside = false
    
    for(int y = 0; y < wBmpHeight; ++y)
    {
        line.top = y;
        line.bottom = y+1;
    
        for(int x = 0; x < wBmpWidth; ++x)
        {
            // I am switching more to pseudo-coding now, but you get the idea :)
            if(RGB(pixel(y*wBmpWidth+x)) == myTransparentColor)
            {
                if(!inside)
                  line.left = x;
            } else
            {
                if(inside)
                {
                   line.right = x-1;   // This makes it go back to the last pixel which was good.
                   inside = false;
    
                   HRGN extra = CreateRectRgnIndirect(&line);
                   CombineRgn(second, second, extra, RGN_XOR);
                   DeleteObject(extra); // this is actually probably what killed your code, btw.
                }
            }
        }
       
        // Make sure to finish a line too
        if(inside)
        {
            line.right = x-1;   // This makes it go back to the last pixel which was good.
            inside = false;
    
            HRGN extra = CreateRectRgnIndirect(&line);
            CombineRgn(second, second, extra, RGN_XOR);
            DeleteObject(extra); // again, we don't want memory leaks.
        }
    }

  4. #4
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Quote Originally Posted by brewbuck View Post
    I suspect you are just creating a region too complicated for Windows to deal with.
    hahaha! You are officially my favorite member.

  5. #5
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102
    Quote Originally Posted by master5001 View Post
    Code:
                   DeleteObject(extra); // this is actually probably what killed your code, btw.
    You are MY favorite member now Thanks, it works flawlessly now, hadn't thought about deleting GDI objects before posting.

    Thanks again!

  6. #6
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    No problemo. I have run into issues like that before and they are so painfully difficult to debug.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange problem with GETLINE
    By wco5002 in forum C++ Programming
    Replies: 13
    Last Post: 07-07-2008, 09:57 AM
  2. Strange problem
    By G4B3 in forum C Programming
    Replies: 6
    Last Post: 05-14-2008, 02:07 PM
  3. Strange problem with classes in header files
    By samGwilliam in forum C++ Programming
    Replies: 2
    Last Post: 02-29-2008, 04:55 AM
  4. Strange problem
    By ~Kyo~ in forum Game Programming
    Replies: 0
    Last Post: 02-14-2006, 10:35 PM