Memory error while using memcpy? - c++

I'm using dcmtk library to modify the pixel data of a multi frame compressed dicom image. So, to do that, at one stage in an for loop I take the pixel data of each decompressed frame and modify them according my wish and try to concatenate each modify pixel data in a big memory buffer frame by frame. This core process of for loop is as below.
The problem is after the first iteration it gives memory at the line of the code where I call the function getUncompressedFrame. I think it's happening because of the line memcpy(fullBuffer+(i*sizeF),newBuffer,sizeF);, as when I remove that line there's no error at that time and the whole for loop works absolutely fine.
Could you please say me if I'm making a mistake in working with memcpy? Thanks.
Uint32 sizeF=828072;// I just wrote it to show what is the data type.
Uint8 * fullBuffer = new Uint8(int(sizeF*numOfFrames));//The big memory buffer
for(int i=0;i<numOfFrames;i++)
{
Uint8 * buffer = new Uint8[int(sizeF)];//Buffer for each frame
Uint8 * newBuffer = new Uint8[int(sizeF)];//Buffer in which the modified frame data is stored
DcmFileCache * cache=NULL;
OFCondition cond=element->getUncompressedFrame(dataset,i,startFragment,buffer,sizeF,decompressedColorModel,cache);
//I get the uncompressed individual frame pixel data
if(buffer != NULL)
{
for(unsigned long y = 0; y < rows; y++)
{
for(unsigned long x = 0; x < cols; x++)
{
if(planarConfiguration==0)
{
if(x>xmin && x<xmax && y>ymin && y<ymax)
{
index=(x + y + y*(cols-1))*samplePerPixel;
if(index<sizeF-2)
{
newBuffer[index] = 0;
newBuffer[index + 1] = 0;
newBuffer[index +2] = 0;
}
}
else
{
index=(x + y + y*(cols-1))*samplePerPixel;
if(index<sizeF-2)
{
newBuffer[index] = buffer[index];
newBuffer[index + 1] = buffer[index + 1];
newBuffer[index + 2] = buffer[index + 2];
}
}
}
}
}
memcpy(fullBuffer+(i*sizeF),newBuffer,sizeF);
//concatenate the modified frame by frame pixel data
}

Change the declaration of fullBuffer to this:
Uint8 * fullBuffer = new Uint8[int(sizeF*numOfFrames)];
Your code didn't allocate an array, it allocated a single Uint8 with the value int(sizeF*numOfFrames).

Uint8 * fullBuffer = new Uint8(int(sizeF*numOfFrames));
This allocates a single byte, giving it an initial value of sizeF*numOfFrames (after truncating it first to int and then to Uint8). You want an array, and you don't want to truncate the size to int:
Uint8 * fullBuffer = new Uint8[sizeF*numOfFrames];
^ ^
or, to fix the likely memory leaks in your code:
std::vector<Uint8> fullBuffer(sizeF*numOfFrames);

If the method getUncompressedFrame is doing an inner memcpy to cache, then it makes sense why, as you are passing a null pointer as argument for the cache, with no memory allocated.

Related

Copying data from a raw image using c++ and objective c

I'm getting a callback from a library that gives me a raw image which is 640*480*4 R8G8B8A8
I did copying it into another buffer then I try to skip the 4th buffer because my framework works only with R8G8B8
I tried to debug and see the bytes in the variable d, but the bytes are all garbage.
-(void)onRawImageBuffer:(NSData * _Nonnull)data withWidth:(int)width andHeight:(int)height andBytesPerPixel:(int)bytesPerPixel;
{
NSUInteger len = [data length];
memcpy(m_CopyData, [data bytes], len);
for(int i =0; i < 640*480*3;i++)
{
if ( i%4 == 3 )
continue;
else{
m_FrameData[i] = m_CopyData[i];
}
}
NSData* d = [NSData dataWithBytes:(const void *)m_FrameData length:640*480*3];
Input::SensorInput::getSingleton()->setVideoData( m_FrameData );
}
You are hard coding width and height;
Your loop must still go to width * height * 4;
You have not allocated m_FrameData;
You are not considering bytesPerPixel;
continue; still advance i by one, you must use two indices;
It's very inefficient, better copy RGB together, skip A, advance src pointer by 4 and dst pointer by 3.

C++ - Heap Corruption on UInt32*

I am currently programming a game on C++ and am working with the SDL 2.0 library.
I am attempting to disect a 32x32 image from a texture to store as a tile and am attempting to recreate it from the pixels of a texture. When I run this code and attempt to edit the Uint32* by a for loop, I can edit it but once I try to creat the image, I get a heap corruption.
I currently have this code running:
Uint32* pixels = (Uint32*)m_pSprite->GetPixels();
int pixelCount = (m_pSprite->GetPitch() / 4) * m_pSprite->GetHeight();
int tileOffset = 0;
int spriteSheetOffset = 0;
int widthOffset = m_pSprite->GetWidth();
Uint32* tilePixels = new Uint32(32);
for (int y = 0; y < 32; y++)
{
tileOffset = (y * 32);
spriteSheetOffset = (y * widthOffset);
for (int x = 0; x < 32; x++)
{
tilePixels[tileOffset + x] = pixels[spriteSheetOffset + x];
}
}
int tilePitch = 32*4;
SDL_Texture* texture = SDL_CreateTexture(backBuffer.GetRenderer(), SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, TILE_WIDTH, TILE_HEIGHT);
I can see that there is something wrong with the Uint32* variable and that this is obviously not a best practice but I am still wrapping my head around what can and cannot be done, and what is the best way etc.
Does anyone have an explanation of what could be happening?
Uint32* tilePixels = new Uint32(32);
This is dynamically allocating a single Uint32, and initializing/constructing it to the value 32. It seems you want a 32*32 array of those. Try this:
Uint32* tilePixels = new Uint32[32*32]; // brackets allocate an array
Although, since the size of your array is static (known at compile-time), it would be best to just use a stack-allocated array instead of a dynamic one:
Uint32 tilePixels[32*32];
See if that fixes it.

pad print line with white space C++

In C++ I am using unsigned char pointers to hold byte arrays so that I can fit 8 bit color codes in each element for a print line.
I have one array holding data, and one array holding white space, and I am using for loops to populate a third array so that the data is at the beginning and white space is at the end.
When the pointer is created, as I monitor memory at runtime, all elements have a default value of 0xCD, which is magenta on color chart. I use a for loop to populate the bytes I want with 0x00, but it will not write over the default array value of the third array.
So, I am stuck with my printer printing magenta instead of white space. Yet I can write over that array just fine with just the data. But not with the whitespace. Im unsure what is the reason for that. Can anyone give me any insight? Here is my code...
PrintLine(unsigned char* pbData, unsigned long ulDataSize, UINT xoffset)
{
if (xoffset > 0)
{ //create pointer to byte array for xoffset
unsigned char* offsetData;
offsetData = new unsigned char[(xoffset / 8)]; //x offset is divided by 8
//to convert pixels to bytes
//create pointer to byte array to hold image data and offset data
unsigned char* finalData;
finalData = new unsigned char[ulDataSize + (xoffset / 8)];
//begin final data with image data passed into the function
for (int count = 0; count < ulDataSize; count++)
{
finalData[count] = pbData[count];
}
//populate offset data with blank bytes
for (int count = 0; count < (xoffset / 8); count++)
{
offsetData[count] = 0x00;
}
//add blank data for offset to finalData
int position = 0;
for (int count = ulDataSize; count < ulDataSize + (xoffset / 8);count++)
{
finalData[ulDataSize] = offsetData[position];//also tried =0x00
position++;
}
//Send data to printer.
if (!(Write(finalData, ulDataSize + (xoffset / 8)))
{
return FALSE;
}
return TRUE;
}
}
At first glance your code don't have errors, but I see something that looks suspicious. I'm talking about the line:
finalData[ulDataSize] = offsetData[position]; //also tried =0x00
I think what you want is:
finalData[count] = offsetData[position];//also tried =0x00
On the other hand you could write your loop like this:
for (int count = 0; count < (xoffset / 8); count++)
{
finalData[ulDataSize + count] = offsetData[count];
}
Making the code much more readable.

C++ - place multiple images in an array pointer

I have been trying to read ten images stored on the disk into an array pointer using the SOIL library. I would like to then render the resulting data in OpenGL using 3D textures.
The code I wrote to read images from the disk and store them in a buffer throws up Access violation reading location 0x00000000 errors.
Is this the right way of storing multiple images using SOIL into an array pointer?
unsigned char *tex;
int imSize = h*w;
unsigned char *buff = new unsigned char[h * w * slices];
for(int i = 1; i<=10; i++)
{
for(int j = 0; j<imSize; j++)
{
if (i==1)
{
tex = (unsigned char*) SOIL_load_OGL_texture("Data/PA_170090.png",
SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID,SOIL_FLAG_INVERT_Y);
buff[((i-1)*imSize) + j] = tex[j]; }
if (i==2)
{ tex = (unsigned char*)SOIL_load_OGL_texture("Data/PA_170091.png",
SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
buff[(i-1)*imSize + j] = tex[j]; }
if (i==3)
{ tex = (unsigned char*)SOIL_load_OGL_texture("Data/PA_170092.png",
SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
buff[(i-1)*imSize + j] = tex[j];}
....
.... // up to 10 images
}
}
It seems SOIL_load_OGL_texture, is not returning any buffer. Instead, it returns an Id (of type GLuint , which is unsigned int). If the function fails, the id will be zero. You are casting that integer value to a pointer and dereferencing it, which results in access violation.

Inserting modified pixel data in a multiframe dicom image?

First I should mention that I'm using the Dcmtk library for this purpose.
I've already managed to learn how I can modify the pixel data of a single frame dicom image. Now,I'm trying to do the same in case of multiframe images. I'm can extract all the necessary information and even can extract the pixel data individually for each frame and can modify them. But the problem arise when I have to insert the modified pixel data. In case of single frame I use the method in DcmDataset:
putAndInsertUint8Array()
But I can't see any option like that for the multi-frame image. I get the pixel data for each frame using this method in DcmElement:
getUncompressedFrame()
where I just have to put the frame index to get the corresponding pixel data. But while inserting I could not find any such option. My programming code is as following:
int main()
{
MdfDatasetManager file;
if(EC_Normal==file.loadFile("test.dcm",ERM_autoDetect,EXS_Unknown))
{
DcmDataset *dataset = file.getDataset();
E_TransferSyntax xfer= dataset->getOriginalXfer();
bool OriginallyCompressed=false;
if(xfer!=0 && xfer !=1 && xfer!=2 && xfer!=3)
{
OriginallyCompressed=true;
DJDecoderRegistration::registerCodecs();
if(EC_Normal==dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL))
{
if(dataset->canWriteXfer(EXS_LittleEndianExplicit))
{
cout<<"Originally it's a compressed image, but now decompressed!\n";
}
}
}
DcmElement* element=NULL;
Uint16 rows = 0;
Uint16 cols = 0;
Uint16 samplePerPixel = 0;
Uint16 planarConfiguration = 0;
int index=0;
// I've fixed these values but later I will change them to dinaymic and make it work as per user's wish.
int ymin=50;//minimum rows
int ymax=500;//maximum rows
int xmin=100;//Minimum columns
int xmax=600;//Maximum columns
if(EC_Normal==dataset->findAndGetUint16(DCM_Rows, rows))
{
if(EC_Normal==dataset->findAndGetUint16(DCM_Columns, cols))
{
if(EC_Normal==dataset->findAndGetUint16(DCM_SamplesPerPixel,samplePerPixel))
{
if(EC_Normal==dataset->findAndGetUint16(DCM_PlanarConfiguration,planarConfiguration))
{
if(EC_Normal==dataset->findAndGetElement(DCM_PixelData,element))
{
Uint32 startFragment=0;
Uint32 sizeF=0;
element->getUncompressedFrameSize(dataset,sizeF);
long int numOfFrames=0;
dataset->findAndGetLongInt(DCM_NumberOfFrames,numOfFrames);
for(int i=0;i<int(numOfFrames);i++)
{
Uint8 * buffer = new Uint8[int(sizeF)];
OFString decompressedColorModel=NULL;
DcmFileCache * cache=NULL;
if(EC_Normal==element->getUncompressedFrame(dataset,i,startFragment,buffer,sizeF,decompressedColorModel,cache))
{
Uint8 * newBuffer = new Uint8[int(sizeF)];
if(buffer != NULL)
{
for(unsigned long y = 0; y < rows; y++)
{
for(unsigned long x = 0; x < cols; x++)
{
if(planarConfiguration==0)
{
if(x>xmin && x<xmax && y>ymin && y<ymax)
{
index=(x + y + y*(cols-1))*samplePerPixel;
newBuffer[index] = 0;
newBuffer[index + 1] = 0;
newBuffer[index +2] = 0;
}
else
{
index=(x + y + y*(cols-1))*samplePerPixel;
newBuffer[index] = buffer[index];
newBuffer[index + 1] = buffer[index + 1];
newBuffer[index + 2] = buffer[index + 2];
}
}
}
}
}
delete newBuffer;
}
delete buffer;
}
}
}
}
}
}
}
return 0;
}
If I just manage to find a way to insert the modified pixel data for each frame, this program will be complete. Please suggest me what I should do. Or please say me, if you know, how the whole pixel data of all the frames in a multiframe dicom image is stored together. Then maybe I can take the whole pixel data together from all the frames and modify them and then try to insert the whole modified pixel data together.
case#1, uncompressed pixel data:
///. get PixelData element in DCM dataset
pDcmDataSet->findAndGetPixelData(...);
///. get pixels in PixelData element
pDcmPixelDataSet->findAndGetOW(...);
You will get the whole pixel data of all the frames in one piece.
case#2, compressed pixel data:
///. get PixelData element in DCM dataset
pDcmDataSet->findAndGetPixelData(...);
///. get PixelSequence in PixelData element
pPixelData->getEncapsulatedRepresentation(...)
///. get PixelItem in PixelSequence
pDcmPixelSequence->getItem(...);
///. get frame in Pixel Item
pPixelItem->getUint8Arrary(...);
You will get one frame of a compressed image.