Re: Starting from the beginning
I have posted a sample zipped cip3 file at www.ed711.com/binary.zip so
you can actually see the contents of a real cip3 file.
This is one of the smaller ones (1meg) as they do get up to 4meg.
So far this is what I have for open/read/search:
void CCIPreadTop::CIPFileRead(CString CipName)
{
int a, i;
unsigned char rawdata[512];
CString errstring;
CString stmp;
CFile f;
if(!f.Open(CipName, CFile::modeRead)){
error = 1; // unable to open file
errstring = _T("Unable to open CIP file");
f.Open(_T("C:\\Adelphi\\cip.dat"), CFile::modeWrite);
f.Write(errstring, errstring.GetLength());//write error to file
f.Close();
return;
}
ULONGLONG len = f.GetLength();
CByteArray buffer;
buffer.SetSize(len + 1);
if(!f.Read(buffer.GetData(), len))
{
error = 2; // unable to read file
f.Close();
errstring = _T("Unable to read CIP file");
f.Open(_T("C:\\Adelphi\\cip.dat"), CFile::modeWrite);
f.Write(errstring, errstring.GetLength());//write error to file
f.Close();
return;
}
buffer[len] = 0;
f.Close();
for (i=0; i<buffer.GetSize(); i++){
if (buffer[i] == 0x00) //strip 0x00 (null) replace with 0x01;
buffer[i] = 0x01;
}
CipStr = (LPCTSTR)buffer.GetData();//copy to CString for text search
a = CipStr.Find(_T("CIP3PreviewImageWidth"), 0);
if (a == -1){
AfxMessageBox(_T("CIP3PreviewImageWidth Keyword Not Found"));
return;
}
a += 22;
stmp = CipStr[a]; //width can be 2, 3, or 4 digit number
a++;
stmp += CipStr[a];
a++;
if (CipStr[a] != 0x20){
stmp += CipStr[a];
a++;
}
if (CipStr[a] != 0x20){
stmp += CipStr[a];
a++;
}
PreviewWidth = atoi(stmp); //PreviewWidth is an int
a = CipStr.Find(_T("CIP3PreviewImageHeight"), 0);
if (a == -1){
AfxMessageBox(_T("CIP3PreviewImageHeight Keyword Not Found"));
return;
}
a += 23;
stmp = CipStr[a]; //height can be 2, 3, or 4 digit number
a++;
stmp += CipStr[a];
a++;
if (CipStr[a] != 0x20){
stmp += CipStr[a];
a++;
}
if (CipStr[a] != 0x20){
stmp += CipStr[a];
a++;
}
PreviewHeight = atoi(stmp); //PreviewHeight is an int
// more processing will be done here like getting the binary data
}
This compiles/works fine with unicode chars set OFF in properties.
With unicode chars set ON it fails the atoi() statement.
1>c:\!vc10projects\adelphi\adelphi\cipreadtop.cpp(87): error C2664:
'atoi' : cannot convert parameter 1 from 'CString' to 'const char *'
On 3/30/2011 12:13 AM, Joseph M. Newcomer wrote:
On Tue, 29 Mar 2011 08:37:40 -0400, Ed<me@right.her> wrote:
I went through this already using VC6 and took a while to fix someone
else s code.
I am starting from scratch now using VS C++ 2010.
Here is what the app needs to do.
I am working with CIP3 ~4meg files containing both text and binary data
(contains 0x00's in the binary part).
The file contains multiple sections of headers followed by binary data.
I need to open, read, separate the binary from the text.
The text tells where the binary part begins and ends.
Example for one section:
CIP3BeginSeparation
/CIP3PreviewImageWidth 581 def
/CIP3PreviewImageHeight 726 def
/CIP3PreviewImageBitsPerComp 8 def
/CIP3PreviewImageComponents 1 def
/CIP3PreviewImageMatrix [ 581.0 0 0 -726.0 0.000000 726.0 ] def
/CIP3PreviewImageResolution [ 12.900000 12.900000 ] def
/CIP3PreviewImageEncoding /Binary def
/CIP3PreviewImageCompression /None def
CIP3PreviewImage
***** Binary data here for x bytes all 8-bit 00-FF *****
CIP3EndSeparation
CIP3BeginSeparation
/CIP3PreviewImageWidth 581 def
/CIP3PreviewImageHeight 726 def
/CIP3PreviewImageBitsPerComp 8 def
/CIP3PreviewImageComponents 1 def
/CIP3PreviewImageMatrix [ 581.0 0 0 -726.0 0.000000 726.0 ] def
/CIP3PreviewImageResolution [ 12.900000 12.900000 ] def
/CIP3PreviewImageEncoding /Binary def
/CIP3PreviewImageCompression /None def
CIP3PreviewImage
***** Binary data here for x bytes all 8-bit 00-FF *****
CIP3EndSeparation
I need to get the ImageWidth as an int
I need to get the ImageHeight as an int
The amount of binary data is width x height bytes.
I need to store the binary data between the text statements.
There can be up to 8 binary sections that all need to be stored separately.
I hope this helps understand what i am trying to do.
Thanks for any help I can get.
****
This is actually a very good question, well-illustrated.
Now, there are many different approaches you can take.
The simplest one, because you are working with such tiny files (4MB) is to do something
along the lines of
...open file file
ULONGLONG length = ..get file length
CByteArray data;
data.SetSize((INT_PTR) length);
// Note the above requires a silly cast because Microsoft has NEVER understood size_t!
// It is remarkably stupid to even consider the possibility that a string or array could
// have a negative size!
file.Read(data.GetData());
now, key here is that you KNOW you are working with 8-bit strings, and it would be a
Really Bad Idea to start converting these to CStringA types (involves gratuitous copy
operations) or try to convert them to Unicode.
Unfortunately, when I tried to find out something about CIP3 format, I found more about
companies selling CIP3 plugins than any technical information, so I can't tell if those
8-bit character strings are NUL-terimated or not.
But this is a case where dropping out of MFC into raw string processing of C. There are
times when C++ abstraction is just overkill, particularly when you end up dealing with 4MB
of copies, which are going to fragment memory rather badly. If I were doing this, I would
not even try to use CStringA or std::string; I'd just go for the raw data. But this is
mostly an issue of performance engineering. If you end up processing several files, you
will waste amazing amounts of time mostly in page faults, plus fragmenting memory that
will make page faults even worse.
If the strings are NUL-terminated, it is a *lot* easier. Just use str functions, or
_atoi, walking a pointer over the file. Do not copy anything. You are in one of those
bizarre situations where I usually use the phrase "rare and exotic circumstances", and
this is *exactly* the kind of situation I have in mind when I use those phrases.
Sometimes, raw engineering has to take precedence over OO elegance. The consequences of
following "best practice" OO design rules here will probably give you unacceptable
performance due to excess copying, excess memory allocation calls, badly fragmented
memory, massive potential for serious page faults,
joe
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm