I've been trying to do this for some time. I can do it with a vector but with a const void*, it crashes badly!

My bad code:

Bitmaps::Bitmaps(const void* Pointer, int Width, int Height, uint32_t BitsPerPixel)
{
    Pixels.clear();
    memset(&Info, 0, sizeof(BITMAPINFO));
    width = Width; height = Height;
    size = ((width * BitsPerPixel + 31) / 32) * 4 * height;

    Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    Info.bmiHeader.biWidth = width;
    Info.bmiHeader.biHeight = height;
    Info.bmiHeader.biPlanes = 1;
    Info.bmiHeader.biBitCount = BitsPerPixel;
    Info.bmiHeader.biCompression = BI_RGB;
    Info.bmiHeader.biSizeImage = size;
    bFileHeader.bfType = 0x4D42;
    bFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(Info.bmiHeader);
    bFileHeader.bfSize = bFileHeader.bfOffBits + size;

    const unsigned char* BuffPos = reinterpret_cast<const unsigned char*>(&Pointer);
    height = (height < 0 ? -height : height);
    Pixels.resize(width * height);
    for (int I = 0; I < height; I++)
    {
        for (int J = 0; J < width; J++)
        {
            Pixels[(height - 1 - I) * width + J].RGBA.B = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.G = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.R = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.A = (Info.bmiHeader.biBitCount > 24 ? *(BuffPos++) : 0);
        }
        if(Info.bmiHeader.biBitCount == 24)
            BuffPos += width % 4;
    }
}

My good code:

Bitmaps::Bitmaps(std::vector<unsigned char> &Pointer, int Width, int Height, uint32_t BitsPerPixel)
{
    Pixels.clear();
    memset(&Info, 0, sizeof(BITMAPINFO));
    width = Width; height = Height;
    size = ((width * BitsPerPixel + 31) / 32) * 4 * height;

    Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    Info.bmiHeader.biWidth = width;
    Info.bmiHeader.biHeight = height;
    Info.bmiHeader.biPlanes = 1;
    Info.bmiHeader.biBitCount = BitsPerPixel;
    Info.bmiHeader.biCompression = BI_RGB;
    Info.bmiHeader.biSizeImage = size;
    bFileHeader.bfType = 0x4D42;
    bFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(Info.bmiHeader);
    bFileHeader.bfSize = bFileHeader.bfOffBits + size;

    unsigned char* BuffPos = &Pointer[0];
    height = (height < 0 ? -height : height);
    Pixels.resize(width * height);
    for (int I = 0; I < height; I++)
    {
        for (int J = 0; J < width; J++)
        {
            Pixels[(height - 1 - I) * width + J].RGBA.B = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.G = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.R = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.A = (Info.bmiHeader.biBitCount > 24 ? *(BuffPos++) : 0);
        }
        if(Info.bmiHeader.biBitCount == 24)
            BuffPos += width % 4;
    }
}

Why does the first one crash? :S I've tried everything.
I use it like:

void __stdcall MyHook_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLint format, GLenum type, const GLvoid *pixels)
{
    if (target == GL_TEXTURE_RECTANGLE || target == GL_TEXTURE_2D)
    {
        Bitmaps BMP(pixels, width, height, 32);
        std::string SavePath = "C:/Users/Foo/Desktop/Images/Foo.bmp"/* + ToString(PI.ID) + ".bmp"*/;
        BMP.Save(SavePath.c_str());
    }

    (*sys_glTexImage2D) (target, level, internalformat, width, height, border, format, type, pixels);
}

Recommended Answers

All 3 Replies

There is a lot of stuff you are doing that has not been defined, such as the Info member/variable, the Pixel class, etc. Without that, debugging this is impossible. Also, have you built this application for debugging, and then run it in the debugger so you can see what is happening directly?

Info Member Variable is defined as BITMAPINFO. Pixels is a vector of RBGA struct which looks like.

typedef union RGB
{
    uint32_t Color;
    struct
    {
        unsigned char B, G, R, A;
    } RGBA;
} *PRGB;

I cannot seem to debug it because it's built into a DLL. The DLL is then loaded by another program (Java program).

At most it gives me:

#

A fatal error has been detected by the Java Runtime Environment:

#

EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x685cfaf0, pid=4892, tid=3348

#

JRE version: 7.0
Java VM: OpenJDK Client VM (21.0-b17 mixed mode windows-x86 )
Problematic frame:
C [OPENGL32.dll+0x8faf0]

#

Failed to write core dump. Minidumps are not enabled by default on client versions of Windows

#

If you would like to submit a bug report, please visit:
The crash happened outside the Java Virtual Machine in native code.
See problematic frame for where to report the bug.

#

--------------- T H R E A D ---------------

Current thread (0x1ae62800): JavaThread "Thread-6" daemon [_thread_in_native, id=3348, stack(0x23170000,0x23370000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000000

Registers:
EAX=0x00000001, EBX=0x2336eef4, ECX=0x00000001, EDX=0x22fc38fe
ESP=0x2336ee64, EBP=0x00000000, ESI=0x00000000, EDI=0x22fc38fe
EIP=0x685cfaf0, EFLAGS=0x00210297

Top of Stack: (sp=0x2336ee64)
0x2336ee64: 2336eef4 00000042 685fdbc0 685c2ae7
0x2336ee74: 00000200 68601bff 00000000 2336eef0
0x2336ee84: 00000001 00000001 00000000 685ba555
0x2336ee94: 2336eef4 00000000 00000001 00000014
0x2336eea4: 2336efcc 2336ef14 5051ff01 2336eef0
0x2336eeb4: 2336eef0 00000000 2336eef0 685682da
0x2336eec4: 2336eef0 00000000 00000001 ffffffff
0x2336eed4: ffffffff 00000030 6ca5e930 00000000

Instructions: (pc=0x685cfaf0)
0x685cfad0: 38 7f dc 89 e8 83 c4 1c 5b 5e 5f 5d c3 8d 76 00
0x685cfae0: 8b 44 24 38 29 e8 39 c8 7e 02 89 c8 89 d7 89 c1
0x685cfaf0: f3 a4 01 c5 01 43 14 39 6c 24 38 7f bc 89 e8 83
0x685cfb00: c4 1c 5b 5e 5f 5d c3 90 8b 44 24 04 8b 10 8b 42

Register to memory mapping:

EAX=0x00000001 is an unknown value
EBX=0x2336eef4 is pointing into the stack for thread: 0x1ae62800
ECX=0x00000001 is an unknown value
EDX=0x22fc38fe is an unknown value
ESP=0x2336ee64 is pointing into the stack for thread: 0x1ae62800
EBP=0x00000000 is an unknown value
ESI=0x00000000 is an unknown value
EDI=0x22fc38fe is an unknown value

Stack: [0x23170000,0x23370000], sp=0x2336ee64, free space=2043k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [OPENGL32.dll+0x8faf0] glDrawElements+0x667cc

[error occurred during error reporting (printing native stack), id 0xc0000005]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j jaggl.OpenGL.glTexImage2Dub(IIIIIIII[BI)V+0
j vq.<init>(Lxd;ILcw;Ldb;II)V+68
j xd.k()V+28
j xd.<init>(Ljava/awt/Canvas;Lma;I)V+1118
j cm.j(Ljava/awt/Canvas;Lma;I)Lra;+7
j nu.x(ILjava/awt/Canvas;Lma;Lky;IIIB)Lra;+80
j ye.j(ILjava/awt/Canvas;Lma;Lky;II)Lra;+52
j lg.ft(ILjava/lang/String;ZI)V+270
j ai.fh(ILjava/lang/String;ZI)V+20
j v.fq(IZI)V+16
J ar.z(I)I
J vw.j(I)V
J client.es(I)V
J client.az(I)V
J mb.a(I)V
j mb.p(B)V+589
j mb.run()V+3
j java.lang.Thread.run()V+11
v ~StubRoutines::call_stub

Uhh I just solved it! LOL such a humilating mistake ={

const unsigned char* BuffPos = reinterpret_cast<const unsigned char*>(&Pointer);

changed to:

const unsigned char* BuffPos = reinterpret_cast<const unsigned char*>(Pointer);

It's the address of that was messing it up.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.