|
When I say bitmap, I don't mean a picture of my missus. I have an array of bytes which represents free slots in a table ( an allocation table ). If a bit is set the slot is used. Within the table of slots records are stored. Each slot has a predetermined size, and each stored record may span one or more slots. The bitmap is used similar to a FAT table.
Testing if a single bit is set is relativly easy, but what is the most efficient way to find a series of unset bits?
For example:
The bitmap = FF983F1F ( 1111 1111 1001 1000 0011 1111 0001 1111 )
record size will span 3 slots, so I need to find a group of 3 unset bits.
at bit #10 there are only 2 slots available
at bit #14 there are 5 available
at bit #24 there are 3 available
I need to quickly find #14 or #24 and convert it to an offset into the slot table. What is the most efficient way of scanning this bitmap?
|
|
|
|
|
I think you can use a look-up table for each byte, though the table must be alittle elaborate, to take into accout sequence of zeroes extending to the neighbours of the bytes themselves.
for instance, if you have
11111000 00111000 ...
must be smart enough to tell you that the empty sequence of the first byte can be continued with that of the following one.
hope that helps.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Hi,
As per my requirement is concerned ,When I press the close(X) button at the top right corner , I need a dialog box to be displayed.Where should I handle (add the code for) this ? Hope I am clear.
Thanks in advance.
Taruni
Taruni
|
|
|
|
|
Handle the WM_CLOSE message.
|
|
|
|
|
In standard Multiple documents project, compile auto create a CChildFrame class that derive from CMDIChildWnd. I overload OnCreate function, In this function I can use GetClientRect() to get window size, but, how can I set size of window?
|
|
|
|
|
Use MoveWindow() or SetWindowPos().
|
|
|
|
|
|
Dear all,
is any body help me in DRM?.
Please code Following.
<br />
WCHAR *Encoder::GenerateKeyID()<br />
{<br />
HRESULT hr;<br />
IWMWriter *m_pWriter = NULL;<br />
hr = WMCreateWriter( NULL, &m_pWriter );
IWMDRMWriter *pDRMWriter = NULL;<br />
hr = m_pWriter->QueryInterface(IID_IWMDRMWriter,(void **) &pDRMWriter);
DWORD d_KeyID = NULL;<br />
hr = pDRMWriter->GenerateKeyID(NULL,&d_KeyID);
WCHAR *w_KeyID = new WCHAR[d_KeyID];<br />
ZeroMemory(w_KeyID,sizeof(WCHAR)* d_KeyID);<br />
hr = pDRMWriter->GenerateKeyID(w_KeyID,&d_KeyID);
return w_KeyID;<br />
}<br />
i caught this error @ debugging and due to this the file remains un protected.
if this will success then and then the file will be protected.
so please help!!
thank you
amit mistry
|
|
|
|
|
Hello, I need help with the following problem.
I am trying to print a PNG image with pixel-by-pixel transparency values. I know there are different ways to accomplish this, some printers have hardware support of the PNG and JPG formats. However, I am doing it in an old-fasioned way, to avoid as much as possible dependency on printer's capabilities.
I load PNG file, convert it into bitmap (32pits-per-pixel) with libpng library, then blend it with whatever background I have currently on a DC, and output the result. There are 2 ways to do this:
1. Using AlphaBlend() function. Unfortunately, none of the printers around (including some brand-new ones) report support for this function, i.e. (GetDeviceCaps(hDC, SHADEBLENDCAPS) & SB_PIXEL_ALPHA) is 0.
2. Reading the contents of the printer's device context using BitBlt() and GetDIBits() calls, manually blending the pixel values, and outputing the result to printer's DC. The printer device reports that it supports both BitBlt() and GetDIBits():
(GetDeviceCaps(hDC, RASTERCAPS) & RC_BITBLT) is non-zero
(GetDeviceCaps(hDC, RASTERCAPS) & RC_DI_BITMAP) is non-zero.
However, the call to GetDIBits() returns me all pixels on printer's DC as black. Here is my code:
//******************************************************************
// hDC is printer's DC in this case
HDC hCaptureDC = CreateCompatibleDC(hDC);
// img structure contains width, height, etc. for the image
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDC, img->width, img->height);
HGDIOBJ h = SelectObject(hCaptureDC, hCaptureBitmap);
ret = BitBlt(hCaptureDC, 0, 0, img->width, img->height, hDC, x, y, SRCCOPY);
if (ret == 0)
{
ret = GetLastError();
goto exit_proc;
}
memset (&bmpInfo, 0, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biBitCount = 32;
// The bitmap identified by the hbmp parameter must not be selected into a device context when the //application calls this function (see MSDN page on GetDIBits), so deselect it:
SelectObject (hCaptureDC, h);
ret = GetDIBits(hCaptureDC,hCaptureBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
if (ret == 0)
{
ret = GetLastError();
goto exit_proc;
}
if (bmpInfo.bmiHeader.biBitCount != 32)
{
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biSizeImage = 0;
}
if(bmpInfo.bmiHeader.biSizeImage<=0)
{
bmpInfo.bmiHeader.biSizeImage = mpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight) * ((bmpInfo.bmiHeader.biBitCount+7)/8);
}
if((pBuf = (BYTE *)malloc(bmpInfo.bmiHeader.biSizeImage))==NULL)
{
ret = -1;
goto exit_proc;
}
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biBitCount = 32;
ret = GetDIBits(hCaptureDC,hCaptureBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
if (ret == 0)
{
ret = GetLastError();
goto exit_proc;
}
//******************************************************************
Is there something I am doing wrong?
P.S. The above code works perfectly on screen DC. The problem occurs only with printers.
|
|
|
|
|
You aren't showing any of the code that sets up hDC (the printer DC).
|
|
|
|
|
Mark, that's because I am being passed a DC. The printer's DC is vaild, I know this because the function actually prints a page, but the result is incorrect: the background pixels that should be seen through the transarent pixels of PNG image (the PNG image is "on the top") are shown as black, and this is direct result of the problem I've described.
|
|
|
|
|
Valid but in what format?
You are using CreateCompatibleDC() and CreateCompatibleBitmap() based on the printer's DC.
This may not be the same format as a screen DC and you said it worked on those.
|
|
|
|
|
Mark, I am not sure about what format you are talking. The image that I have
am trying to "capture" is in a device-specific format (in this case, printer's). I know that printer's DC is different from screen. This is why I am using DC-compatible bitmap and all this. Problem is that GetDIBits() works perfect with screen-compatible DC, but returns all pixels as black with printer-compatible DC. So far, I don't see where my mistake is. It could be that it's "normal" for printer DC, but then GetDIBits() (or any other function) does not return any error code, and GetDeviceCaps() says this capability is supported. Could it be that MSDN is not telling the truth?
|
|
|
|
|
Correct. Does this mean that GetDIBits() returns me data in some different format? I am calling
ret = GetDIBits(hCaptureDC,hCaptureBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
where
bmpInfo.bmiHeader.biBitCount = 32 and
bmpInfo.bmiHeader.biCompression = BI_RGB.
It returns me 187 (number of lines (height) in the image), which is a successful return code. When I look at the pBuf array though, all pixels are set to black.
|
|
|
|
|
hmm I'm going to back up to the beginning on this one. I may have careened way off course here
The more I think about it the more I think it should be working as you have it so one of us
is missing something.
If you do this...
HDC hCaptureDC = CreateCompatibleDC(hDC);
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDC, img->width, img->height);
HGDIOBJ h = SelectObject(hCaptureDC, hCaptureBitmap);
BITMAP bitmap;
::GetObject(hCaptureBitmap, sizeof(BITMAP), &bitmap);
... then what are the values in "BITMAP bitmap"?
I'd like to test it out with the same kind of bitmap.
Mark
|
|
|
|
|
Mark, I have a piece of code for you so that you could just copy & paste into your program and try it. To test, call PrintBmp () function passing it a valid window handle (HWND). The function prints a small rectangle in the top left corner of the page; rectangle has white and gray pixels. Function GetPrinterBits() then gets the pixels from the same rectangle. It's easy to see that they are all returned as black (all zero), i.e. valid_image is FALSE. Let me know if you have any questions.
#include "commdlg.h"
#include "stdio.h"
typedef struct tagIMAGE {
LONG width;
LONG height;
UINT pixdepth;
DWORD imgbytes;
BYTE *bmpbits;
} IMAGE;
void SetFlagLong (DWORD &flags, DWORD flagToSet, bool onOff=true)
{
if (onOff)
flags |= flagToSet;
else
flags &= ~flagToSet;
}
BYTE * GetPrinterBits (HDC hDC, IMAGE *img, int x, int y, int &ret)
{
BITMAPINFO bmpInfo;
BYTE *pBuf = NULL;
bool valid_image = false;
HDC hCaptureDC = CreateCompatibleDC(hDC);
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDC, img->width, img->height);
HGDIOBJ h = SelectObject(hCaptureDC, hCaptureBitmap);
ret = BitBlt(hCaptureDC, 0, 0, img->width, img->height, hDC, x, y, SRCCOPY);
memset (&bmpInfo, 0, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biCompression = BI_RGB;
SelectObject (hCaptureDC, h);
ret = GetDIBits(hCaptureDC,hCaptureBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
if (ret == 0)
{
ret = GetLastError();
goto exit_proc;
}
if (bmpInfo.bmiHeader.biBitCount != 32 || bmpInfo.bmiHeader.biCompression != BI_RGB)
{
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biSizeImage = 0;
}
if(bmpInfo.bmiHeader.biSizeImage<=0)
{
bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*((bmpInfo.bmiHeader.biBitCount+7)/8);
}
if((pBuf = (BYTE *)malloc(bmpInfo.bmiHeader.biSizeImage))==NULL)
{
//MessageBox( NULL, "Unable to Allocate Bitmap Memory", "Error", MB_OK|MB_ICONERROR);
ret = -1;
goto exit_proc;
}
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biBitCount = 32;
ret = GetDIBits(hCaptureDC,hCaptureBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
if (ret == 0)
{
ret = GetLastError();
goto exit_proc;
}
else
{
for (int i=0; i<bmpinfo.bmiheader.bisizeimage;i++)
{
="" if="" (*(pbuf="" +="" i)="" !="0)
" valid_image="true;
" break;
="" }
="" (!valid_image)=""
="" free="" (pbuf);
="" pbuf="NULL;
" }
exit_proc:
="" deletedc(hcapturedc);
="" deleteobject(hcapturebitmap);
="" return="" pbuf;
}
int="" printpicture="" (hdc="" hdc,="" image="" *img,="" int="" x,="" y)
{
="" unsigned="" long="" ulpngwidth="img-">width;
unsigned long ulPngHeight = img->height;
unsigned long ulDstX=x, ulDstY=y;
unsigned long ulDstWidth, ulDstHeight;
long imgbytes=0;
HDC hDCScreen = GetDC(NULL);
int nScreenX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
int nScreenY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
ReleaseDC(NULL,hDCScreen);
double x_ratio = (double)GetDeviceCaps (hdc, LOGPIXELSX)/nScreenX;
double y_ratio = (double)GetDeviceCaps (hdc, LOGPIXELSY)/nScreenY;
ulDstWidth = (double)ulPngWidth * x_ratio;
ulDstHeight = (double)ulPngHeight * y_ratio;
int iRet=0;
BITMAPINFO bmi;
int ret2;
IMAGE img2;
img2.height = img->height * y_ratio;
img2.width = img->width * x_ratio;
img2.pixdepth = img->pixdepth;
img2.bmpbits = NULL;
img2.imgbytes = 0;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = ulPngWidth;
bmi.bmiHeader.biHeight = ulPngHeight; // top-down image
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = img->pixdepth;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = img->imgbytes;
iRet = StretchDIBits(
hdc, // handle to DC
ulDstX, // x-coord of destination upper-left corner
ulDstY, // y-coord of destination upper-left corner
ulDstWidth, // width of destination rectangle
ulDstHeight, // height of destination rectangle
0, // x-coord of source upper-left corner
0, // y-coord of source upper-left corner
img->width, // width of source rectangle
img->height, // height of source rectangle
img->bmpbits, // bitmap bits
&bmi, // bitmap data
DIB_RGB_COLORS, // usage options
SRCCOPY);
BYTE * pix = GetPrinterBits (hdc, &img2, x, y, ret2);
int ret = 0;
if (pix)
{
free (pix);
ret = 1;
}
return ret;
}
void PrintBmp (HWND hWnd)
{
PRINTDLG printDev;
IMAGE img;
img.width = 35;
img.height = 38;
img.pixdepth = 32;
img.imgbytes = img.width * img.height * 4;
img.bmpbits = (unsigned char *)malloc(img.imgbytes);
memset (img.bmpbits, 0, img.imgbytes);
BYTE *ptr = img.bmpbits;
for (int i = 0; i < img.height; i++)
for (int j = 0; j < img.width; j++)
{
*ptr = ((i + j) & 1) ? 128 : 256;
*(ptr + 1) = ((i + j) & 1) ? 128 : 256;
*(ptr + 2) = ((i + j)& 1) ? 128 : 256;
*(ptr + 3) = 0;
ptr += 4;
}
memset(&printDev, 0, sizeof(PRINTDLG));
printDev.lStructSize = sizeof(PRINTDLG);
printDev.Flags = PD_RETURNDC | PD_HIDEPRINTTOFILE | PD_NOPAGENUMS |
PD_NOSELECTION |
PD_USEDEVMODECOPIES;
SetFlagLong (printDev.Flags, PD_PRINTSETUP, false); // Turn off print setup
SetFlagLong (printDev.Flags, PD_RETURNDEFAULT, false);
SetFlagLong (printDev.Flags, PD_RETURNDC, true);
printDev.hwndOwner = hWnd;
if (!PrintDlg(&printDev))
return;
DOCINFO docInfo;
docInfo.cbSize = sizeof (docInfo);
docInfo.lpszDocName = "test";
docInfo.lpszOutput = NULL;
docInfo.lpszDatatype = NULL;
docInfo.fwType = 0;
int ret = 0;
ret = StartDoc(printDev.hDC, &docInfo);
if (0 < ret)
{
if (StartPage(printDev.hDC) >= 0)
{
PrintPicture (printDev.hDC, &img, 0, 0);
EndPage (printDev.hDC);
}
EndDoc(printDev.hDC);
}
else
{
ret = GetLastError();
}
DeleteDC(printDev.hDC);
free (img.bmpbits);
}
|
|
|
|
|
Thanks. Can you modify your post to ignore html tags? Lost some < in there
I may be able to figure 'em out.
|
|
|
|
|
Really? I don't see anything lost. One correction though:
*ptr = ((i + j) & 1) ? 128 : 256;
*(ptr + 1) = ((i + j) & 1) ? 128 : 256;
*(ptr + 2) = ((i + j)& 1) ? 128 : 256;
*(ptr + 3) = 0;
ptr += 4;
should be
*ptr = ((i + j) & 1) ? 128 : 255;
*(ptr + 1) = ((i + j) & 1) ? 128 : 255;
*(ptr + 2) = ((i + j)& 1) ? 128 : 255;
*(ptr + 3) = 0;
ptr += 4;
to make half of the pixels white. It's not that important, just to be accurate.
|
|
|
|
|
there was just one < in a for-loop.
|
|
|
|
|
Yes, now I see it. It was:
for (int i=0; i<bmpInfo.bmiHeader.biSizeImage; i++)
{
if (*(pBuf + i) != 0)
{
valid_image = true;
break;
}
}
|
|
|
|
|
OK
I've been over this code for hours
The only thing I can figure is that printer driver doesn't handle BitBlt FROM its DC.
Everything checks out until the BitBlt. I've saved DIBs and Bitmaps at all points so I could
look at them externally and they are all fine until the BitBlt() then it's all black.
(by the way, i figured/assumed the missing for-loop part, thanks )
|
|
|
|
|
It looks like this, even though it reports this capability (via GetDeviceCaps()). Now, the question is: how can I print a transparent image? AlphaBlend() is not supported on printer. The only other way to do this, as I mentioned before, is to get the pixels from a printer's DC. But they are always returned as black with BitBlt() and GetPixel() returns CLR_INVALID for any pixel for printer's DC. It's a puzzle to me.
|
|
|
|
|
I don't know if this works on printer DCs...
ImageList_Create() with ILC_COLOR32|ILC_MASK flags
ImageList_AddMasked()
ImageList_Draw()
|
|
|
|
|
I doubt it. Can you try it in your app?
I have a feeling it's a common problem with PNG images with partial transparency. Just type "print transparent image" in Google and see how many complaints about bad or simply missing functionality all kinds of programs have in this regard.
|
|
|
|
|
I doubt it too. If you can't read (blt) from a printer DC why would masked operations work.
I'm going to try both (image mask and PNG image) though
I'll be back...
|
|
|
|
|