|
Hey guys,
Im having a problem with the CImage::GetBits(). Im opening a TIFF file using a CImage object, and i want to take information from this image for use in another function. Here is whats happening.
unsigned char* chBitBuffer = new unsigned char;<br />
chBitBuffer = (unsigned char*)image->GetBits();
This compiles, and appears to work fine, but after several access violations I went a bit deeper.
image's height = 1179, width = 673, bits per pixel = 32.
So Im assuming that the number of pixels = height * witdth. Number of pixels * 4 = total number of bytes, since each pixel is 4 bytes (32/8).
The problem comes in when I try to access the data returned from GetBits(). The buffer only has a length of 3224 in this example, when my calculations say it should be as long as the number of bytes(3173868).
Any clues to what may be going on here?
I win because I have the most fun in life...
|
|
|
|
|
VonHagNDaz wrote: unsigned char* chBitBuffer = new unsigned char;
chBitBuffer = (unsigned char*)/*the image*/image->GetBits();
Why you are allocating memory on heap here ? Actually, GetBits returns address to buffer.
Its should be something like this,
BYTE *pBits = (BYTE*)m_image.GetBits();
p.s. Questions not involving CLI should be asked in VC++[^] forum.
|
|
|
|
|
im being called to a meeting, i will test this as soon as i can get back to my desk.
about the wrong forum, apparently i miss clicked, the vc++ is the link above this forums, sorry
I win because I have the most fun in life...
|
|
|
|
|
In addition to prasad_som's reply...
The total number of pixels should be determined by (pseudocode):
ABS(CImage::GetPitch()) * CImage::GetHeight()
Also, for bottom-up DIBs (CImage::GetPitch() is negative), CImage::GetBits() will return a
pointer to the last row of bits.
Where are you getting the value for the length of the buffer?
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
to get the length i just put together a "stupid" for loop
for(i = 0; i < 9999999; i++)
buffer[i] = 0;
then i let it go until it threw the out of bounds exception
I win because I have the most fun in life...
|
|
|
|
|
So did GetBits() return a pointer to the last row of pixels?
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
oh, sorry i left that out, the image is bottom up, pitch = - 2692, which is also the size i calculated for a scanline of the image +2692.
I win because I have the most fun in life...
|
|
|
|
|
VonHagNDaz wrote: the image is bottom up, pitch = - 2692
Then CImage::GetBits() returns a pointer to the last row of pixels.
To get the beginning of the buffer I suppose something like this would work:
BYTE *pBits = (BYTE *)image.GetBits() + (image.GetPitch() * (image.GetHeight() - 1))
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
alright, im now using the pointer to the pixels, and accessing them using:
<br />
BYTE* pHold;<br />
<br />
int nScanlineIndex = 0;<br />
<br />
while(nScanlineIndex < nTotalBytes)<br />
{<br />
for(int j = 0; j < nScanlineSize; j++)<br />
{<br />
pHold[j] = pBits[nScanlineIndex];<br />
nScanlineIndex++;<br />
}<br />
<br />
scanline->data = (char*)&pHold;<br />
<br />
if(!dither->PerformDither(scanline, ditheredScanline) == S_OK)<br />
return false;<br />
<br />
memset(pHold, 0, nScanlineSize);<br />
}<br />
scanline index counts the bytes of the entire image,which i use to keep track of the position of the byte array. I then transfer the information to the pHold buffer, when is large enough to hold the data of one scanline. the rest is calls to functions of another class that i am using the information for.
I win because I have the most fun in life...
|
|
|
|
|
Is it working? Is nScanlineSize the absolute value of the stride/pitch?
You don't show pHold being allocated so the code as shown should crash.
Also this doesn't look right: scanline->data = (char*)&pHold;
If scanline->data needs a pointer to the pixels then it should be scanline->data = (char*)pHold;
As shown, you are assigning scanline->data the address of the pointer, cast to a char*.
Maybe that's the way it should be but it looks suspicious.
Here's a simplified version of your code, taking advantage of the signed GetPitch() value.
Note that you don't nned to know if GetBits points to the last row or the first row in memory
because GetPitch() will move the pointer in the right direction:
BYTE *pBits = (BYTE *)image.GetBits();
int nScanlineSize = (image.GetPitch() > 0) ? image.GetPitch() : -image.GetPitch();
BYTE *pHold = new BYTE[nScanlineSize];
for (int nCurRow = 0; nCurRow < image.GetHeight(); ++nCurRow)
{
memcpy(pHold, pBits, nScanlineSize);
scanline->data = (char*)pHold;
if(!dither->PerformDither(scanline, ditheredScanline) == S_OK)
{
delete[] pHold;
return false;
}
pBits += image.GetPitch();
}
delete[] pHold;
Do you need to copy the rows of pixel data to a buffer (does dither->PerformDither alter the
source data)? If not, then you could simplify the loop.
BYTE *pBits = (BYTE *)image.GetBits();
for (int nCurRow = 0; nCurRow < image.GetHeight(); ++nCurRow)
{
scanline->data = (char*)pBits;
if(!dither->PerformDither(scanline, ditheredScanline) == S_OK)
return false;
pBits += image.GetPitch();
}
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Hi All,
I'm trying to overload the assignment (=) operator so that I can achieve the following:
int x = myclass;
instead of:
int x = myclass.Value();
I am implementing it as follows:
class CMyClass
{
private:
int m_nValue;
public:
int& operator=(CMyClass& class);
int Value() { return m_nValue; };
};
int& CMyClass::operator=(CMyClass& class)
{
return class.Value();
}
But I keep on getting a compiler errors either saying that there is no suitable conversion, or that it cannot convert from CMyClass to int.
Clearly my syntax (or something) is screwed, so how can I fix it ?
Thanks
OD
|
|
|
|
|
This forum is meant for managed C++. You have rightly asked it in VC++[^] forum. So, please dont cross-post.
|
|
|
|
|
How can i get the system time?
|
|
|
|
|
DateTime.Now. If this does not work, then you're not using C++/CLI, and have asked in the wrong forum.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Use GetSystemTime .
SYSTEMTIME systime;
GetSystemTime(&systime);
ps. Question not involving CLI should be asked in VC++[^] forum.
|
|
|
|
|
Thanks for the information
|
|
|
|
|
Hello,
How to communicate with USB devices from VC++.NET code?
Thanks for help,
Regards
|
|
|
|
|
Hi,
I'm trying to deploy an application written in C++, C++/CLI and C# on pc's that do not have VC2005 installed. I am having issues with assemblies loading, in particular the C++/CLI one and am getting FileLoadException when it tries to load the dll. I know I can get round this problem by running Vcredist_x86.exe - this sorts it out and sets the pc up so that it can run VS2005 apps.
My problem however is that not everybody is able to run this exe as you need admin rights as it's an installer, so I just want to be able to ship the appropriate dlls with the application. These can be found in the folders in \Program Files\Microsoft Visual Studio 8\VC\Redist\x86\ in my installation. However, even with these dlls present in the application directory (both within their directory structures and just all copied straight into the root directory), I'm still getting the FileLoadException when trying to load the C++/CLI dll. Does anyone know what else Vcredist_x86.exe does, i.e. what other dlls it puts on the users pc. I feel like I've tried all avenues but am not getting anywhere...
There's a lot of detail about this at http://www.codeproject.com/cpp/vcredists_x86.asp but I've tried it all and the only way I can get it to work is by running the VcRedist_x86.exe which unfortunately isn't an option.
Thanks, Stuart
|
|
|
|
|
More info: Deployment (C++)[^]
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
In my project, i have to transfer some data from a gprs modem to a pc. So I just want to learn that, Is TCPListener component sufficient for obtaining the data sent by GPRS modem over GPRS channel?
|
|
|
|
|
Hi to all, I'm new to vc++ and I've read a bit on how to create a new form and load it (make it appear on screen). But i have this code and its corresponding error and would be glad if someone could point me in the right direction.
There's three forms, Form1 (login form) and gymMain a main interface. So what I tried to do is first load the application with gymMain and make its Visible state FALSE, next load Form1 (login) and upon confirmation of input, close Form1 and make gymMain visible. Now I try this with the below code and the erorr is shown below. All help/suggestions appreaciated.
regards
PS: I'm prety sure I used the header files appropriately but one never knows, ...
--------------------------
code for Main application:
--------------------------
// GymManager.cpp : main project file.
#include "stdafx.h"
#include "Form1.h"
#include "gymMain.h"
#include "NewMember.h"
#include "search.h"
using namespace GymManager;
//using namespace Form1;
//using namespace gymMain;
//using namespace NewMember;
//using namespace search;
[STAThreadAttribute]
int main(array ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew gymMain());
return 0;
}
----------------------------------------
code for gymMain:
----------------------------------
#pragma once
#include "NewMember.h"
#include "Form1.h"
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Globalization;
using namespace GymManager;
namespace GymManager {
///
/// Summary for gymMain
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
///
//
//// code for constructor and object declarations and initializations
//
#pragma endregion
private: System::Void btnNewM_Click(System::Object^ sender, System::EventArgs^ e) {
// gymMain::Visible = false;
// GymManager::NewMember ^newM = gcnew GymManager::NewMember;
// newM->Show();
}
private: System::Void gymMain_Load(System::Object^ sender, System::EventArgs^ e) {
//load login page and make main page invisible
this->Visible = false;
GymManager::Form1 ^login = gcnew GymManager::Form1;
login->Show();
//display clock
DateTime^ dt = DateTime::Now;
String^ date;
date = dt->ToString();
lDateShow->Text = date;
}
};
}
-------------------------------
error messages displayed:
-------------------------------
c:\documents and settings\and_one\my documents\visual studio 2005\cs208\gymmanager\gymmanager\gymMain.h(282) : error C2039: 'Form1' : is not a member of 'GymManager'
c:\documents and settings\and_one\my documents\visual studio 2005\cs208\gymmanager\gymmanager\gymMain.h(282) : error C2065: 'Form1' : undeclared identifier
c:\documents and settings\and_one\my documents\visual studio 2005\cs208\gymmanager\gymmanager\gymMain.h(282) : error C2065: 'login' : undeclared identifier
c:\documents and settings\and_one\my documents\visual studio 2005\cs208\gymmanager\gymmanager\gymMain.h(282) : error C2039: 'Form1' : is not a member of 'GymManager'
c:\documents and settings\and_one\my documents\visual studio 2005\cs208\gymmanager\gymmanager\gymMain.h(282) : error C2061: syntax error : identifier 'Form1'
c:\documents and settings\and_one\my documents\visual studio 2005\cs208\gymmanager\gymmanager\gymMain.h(283) : error C2227: left of '->Show' must point to class/struct/union/generic type
type is ''unknown-type''
luhfluh
|
|
|
|
|
As said earlier Form1 doesn't seem to member of GymManager , which is assumed by you while coding.
|
|
|
|
|
If I have a populated dataGrid in visual c++, how can I get values from the dataGrid without going to the underlying dataSet.
Is there a way to use dataGrid->currentRowIndex to reference the row and then return the value from a given column.
Thanks!!
Kim
|
|
|
|
|
You need to populate the dataset...
"I've seen more information on a frickin' sticky note!" - Dave Kreskowiak
|
|
|
|
|
How do I perform a global hit test?
I want to translate the mouse coords to a global hit test result which will hopefully give me the window handle that the mouse is over and if possible, if I am over the title bar/menu/status bar etc.
http://www.asura.co.uk
|
|
|
|