This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Sorry this is long. I�ve been pulling my hair out and really need help.
I am working with a new API that simplifies JNI. It�s great. JNative. There is not a ton of documentation but it�s pretty simple.
To use JNative, you have to implement your structure to match the C structure, call your C method, invoke and get your return value. Pretty simple. Where I am having problems is in how the API is written (my ignorance of C++) and in missing operators in Java (in C you can say �sizeof(HANDLE)� in Java you have to add up the bits).
I�m trying to get a BMP image to a DLL for OCR. To do that, I have to have a �BITMAPHANDLE�. Here�s a little overview of JNative.
Basic Data Types: UINT (short value) � up to 16 bits or 4 bytes LONG (int value) � up to 32 bits or 4 bytes INT64 (long value) � up to 64 bits or 8 bytes
The only other object I use from JNative in this structure is Pointer.
In my method, I need a Pointer to a BITMAPHANDLE, pBITMAPHANDLE. The API tells me which fields I can set and the layout of the bitmaphandle structure. The types in the API and how I matched them up in JNative follow:
L_UINT 16 bit unsigned integer � UINT in JNative L_INT 16 bit signed integer � LONG in JNative L_BITFIELD defined as L_UINT � UINT in JNative L_BOOL defined as L_UINT � UINT in JNative L_UINT32 defined as long used as signed 32 bit integer � LONG in JNative
There are 29 UINT, INT, BOOL and BITFIELD variables defined. That�s 464 bits. There are three UINT32 variables defined. That�s 96 bits. There is a pointer to an array of palette colors. I just defined that pointer as the following: Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(16)); Anyway, that�s 32 more bits because pointers are 4 bytes. I also have to pass in two (2) COLORREF�s which is the return value of the Windows RGB macro. That one is giving me fits too but I think I�ve got another 16 bits as it seems like the RGB returns a byte. I�ve never done any Windows type programming so I�m having trouble there too.
The total of all of these variables (if I�m right on all of them) means my structure size is 76 bytes.
I run it and get a return from the DLL (a good sign) which is -789. That�s an error code. It means, �Invalid Structure Size�. I then see the API says: �Fields intended for internal use, such as the pointer to the bitmap, are omitted from the table. If necessary, you can refer to the LTKRN.H header file, which describes the entire structure.� Great!
I�ve looked at the .H file but it�s a mess to me. The part I think is relevalnt follows:
Much of the above is way foreign to me.
Here is what the API Says
Note: Fields intended for internal use, such as the pointer to the bitmap, are omitted from the table. If necessary, you can refer to the LTKRN.H header file, which describes the entire structure.
Member Data Type Description
uStructSize L_UINT Size of this structure in bytes, for versioning. Use the sizeof() macro to calculate this value.
Width L_INT Image width in pixels.
Height L_INT Image height in pixels.
BitsPerPixel L_INT Number of bits per pixel.
BytesPerLine L_UINT Bytes per line, rounded upward to the nearest multiple of four.
Flags.Allocated L_BITFIELD TRUE if the bitmap is allocated.
Flags.ConventionalMemory L_BITFIELD TRUE if the bitmap is allocated using conventional memory.
Flags. DiskMemory L_BITFIELD TRUE if the bitmap is allocated using LEAD's own virtual memory.
Flags.LockedMemory L_BITFIELD TRUE if the bitmap memory is locked down.
Flags.Progressive L_BITFIELD TRUE if an image is being loaded from a progressive JPEG file.
Flags.Tiled L_BOOL TRUE if the bitmap is a tiled bitmap.
Flags.WaitUserInput L_BITFIELD TRUE if the animation playback waits for user input.
Flags.Transparency L_BITFIELD TRUE if the animation playback uses transparency.
Flags.Compressed L_BITFIELD TRUE if the current bitmap is in 1-bit RLE-compressed format. For information about this format, refer to Speeding Up 1-Bit Documents.
Flags.Signed L_BITFIELD TRUE if the pixel values in the bitmap are signed.
Flags.SuperCompressed L_BITFIELD TRUE if the bitmap is in super compressed format. The bitmap can be 24-bit or 1-bit. For more information, refer to Super Compressed Bitmaps.
Flags.UseLUT L_BITFIELD TRUE if the LUT is used in all image processing functions, including save. FALSE if the LUT is used only when painting. If this is FALSE, the LUT is ignored when an image processing function is applied or when a file is saved.
nColors L_INT Number of colors (256 or less) that the bitmap has. If the image has more than 256 colors, this value is zero.
pPalette L_RGBQUAD L_FAR* Array of palette colors.
ViewPerspective L_INT Where the beginning of the image is stored. Valid values are TOP_LEFT, BOTTOM_LEFT, TOP_RIGHT, BOTTOM_RIGHT, TOP_LEFT90, and TOP_LEFT270. For descriptions, refer to Accounting for View Perspective.
Order L_INT Color order of the bitmap. Possible values are ORDER_RGB, ORDER_BGR, ORDER_GRAY and ORDER_ROMM.
Size L_UINT32 Size of the bitmap image data, in bytes.
DitheringMethod L_UINT Dithering method (referenced by some functions). For possible values, refer to the L_DefaultDithering function.
XResolution L_INT Horizontal resolution, in dots per inch. Some file formats save this value in the file header.
YResolution L_INT Vertical resolution, in dots per inch. Some file formats save this value in the file header.
Left L_INT Left offset for animation playback.
Top L_INT Top offset for animation playback, based on a TOP_LEFT view perspective.
Delay L_UINT32 Animation playback delay in milliseconds (ms).
Background COLORREF Background color for animation playback. You can specify a COLORREF value, such as the return value of the Windows RGB macro, or you can use the PALETTEINDEX macro to specify a palette color.
Transparency COLORREF Transparent color for animation playback. You can specify a COLORREF value, such as the return value of the Windows RGB macro, or you can use the PALETTEINDEX macro to specify a palette color.
DisposalMethod L_UINT Animation playback disposal method. For possible values, refer to Animation Disposal Methods.
LowBit L_INT Value indicating the low bit used for window leveling. 0 <= nLowBit <= nHighBit <= (11 for 12-bit grayscale or 15 for 16-bit grayscale). A value of -1 will be treated as 0.
HighBit L_INT Value indicating the high bit used for window leveling. 0 <= nLowBit <= nHighBit <= (11 for 12-bit grayscale or 15 for 16-bit grayscale). A value of -1 will be treated as BitsPerPixel -1.
MinVal L_INT32 Minimum grayscale value. For every value between 0 and MinVal, Black (RGB(0,0,0)) will be used. For values between MinVal and MaxVal, the gray value to be displayed is calculated by : gray = (index - MinVal) * 255 / (MaxVal - MinVal).(See * below)
MaxVal L_UINT Maximum grayscale value. For every value larger than MaxVal, White (RGB(255,255,255)) will be used. For values between MinVal and MaxVal, the gray value to be displayed is calculated by : gray = (index - MinVal) * 255 / (MaxVal - MinVal). (See * below)
* index is the intensity value of the pixel. If the intensity value is > MaxVal, the color will be White. If the intensity value is < MinVal, the color will be Black. For those intensity values between MinVal and MaxVal, the above equation is used to determine the color, with index equal to the intensity value.
That's the bitmaphandle. Here's the method I'm calling:
L_CHAR L_FAR* pBuffer; /* pointer to the file in memory to be loaded */ pBITMAPHANDLE pBitmap; /* pointer to the target bitmap handle */ L_UINT uStructSize; /* size in bytes, of the structure pointed to by pBitmap */ L_INT nBitsPerPixel; /* resulting bitmap pixel depth */ L_INT nOrder; /* color order for 16-, 24-, 32-, 48- and 64-bit bitmaps */ L_INT32 nBufferSize; /* size of the file in memory (in bytes) */ pLOADFILEOPTION pLoadOptions; /* pointer to optional extended load options */ pFILEINFO pFileInfo; /* pointer to a structure */
Loads an image file from memory into a bitmap. The file in memory can be in any supported image file format and bits per pixel, whether compressed or uncompressed.
pBuffer Pointer to the file in memory to be loaded. pBitmap Pointer to the bitmap handle referencing the target bitmap. uStructSize Size in bytes, of the structure pointed to by pBitmap, for versioning. Use sizeof(BITMAPHANDLE). nBitsPerPixel Resulting bitmap pixel depth. The following are valid values:
0 Keep the original file's pixel depth (Do not convert). A special note about loading 12 and 16-bit grayscale images. 1 to 8 The specified bits per pixel in the resultant bitmap 12 12 bits per pixel in the resultant bitmap. 16 16 bits per pixel in the resultant bitmap 24 24 bits per pixel in the resultant bitmap 32 32 bits per pixel in the resultant bitmap 48 48 bits per pixel in the resultant bitmap 64 64 bits per pixel in the resultant bitmap
nOrder Color order for 16-, 24-, 32-, 48-, 64-bit bitmaps. If the resultant bitmap is less than 16 bits per pixel, this will have no effect since palletized images have no order. The following are valid values:
ORDER_RGB  Red, green, and blue color order in memory ORDER_BGR  Blue, green, and red color order in memory ORDER_GRAY  12 or 16-bit grayscale image. 12 and 16-bit grayscale images are only supported in the Document/Medical Imaging editions . ORDER_RGBORGRAY  Load the image as red, green, blue OR as a 12 or 16-bit grayscale image. 12 and 16-bit grayscale images are supported in the Document/Medical Imaging editions only. ORDER_BGRORGRAY  Load the image as blue, green, red OR as a 12 or 16-bit grayscale image. 12 and 16-bit grayscale images are supported in the Document/Medical Imaging editions only. ORDER_ROMM  ROMM order. ROMM only supports 24 and 48-bit images. ORDER_BGRORGRAYORROMM  Load the image as red, green, blue OR as a 12 or 16-bit grayscale image OR as ROMM. 12 and 16-bit grayscale images are supported in the Document/Medical Imaging editions only. ROMM only supports 24 and 48-bit color images.
nBufferSize Size of the file in memory (in bytes).
pLoadOptions Pointer to optional extended load options. Pass NULL to use the default load options.
pFileInfo Pointer to a FILEINFO structure. This structure may contain file information used in loading an image, or it may be updated with information about the file being loaded. Returns
SUCCESS The function was successful.
< 1 An error occurred. Refer to Return Codes.
I pass null pointers for pLoadOptions and pFileInfo which the API says is okay to do.
Finally, here's my implementation in JNative:
Okay finally, here is the relevant code for the structure which is instantiated in the above object:
I�m embarrassed to post so much and ask for your help. If you do read this tome and help me, thank you so very much.
You can't look at a C structure definition and determine the size of the structure with 100% accuracy. The compiler may add padding to align certain members on 16, 32, or 64-bit boundaries. This is compiler- and architecture-dependent. What you have to do is use the "sizeof" operator, as you noted. Write a little C program that just uses sizeof to print the true size of the structure, then use that value. If possible, try to determine it at runtime, and pass it back to Java, if needed, to make your code more portable. [ June 19, 2006: Message edited by: Ernest Friedman-Hill ]