Jens said:
markww wrote:
In the worst case scenario I'll have about 300 elements in the vector
all with [512 * 512 * 3] pixels. I may have as many as 5 such vectors.
Will sort() still perform quickly give that situation?
As you did it, the [512 * 512 * 3] pixels are not copied, only a pointer
to it along with an int and a string instance.
So then it should be pretty quick.
However, I suggested using stl containers instead of raw pointers;
normally std::vector will copy it's data if it's copied - but std::sort
doesn't actually copy, it swaps. And swapping std::vectors works in
constant time - so it's fast again.
Jens
Ok maybe you guys can recommend a better structure design. In my app a
user will load 100 for example. Each image is represented by that
structure:
struct Image {
Image() { pPix = NULL; }
~Image() { if (pPix) delete [] pPix; }
string strStudyID;
string strSeriesID;
string strImageID;
int nNumber;
double dPosition;
BYTE *pPix;
};
Now my original idea was that as the user is scrolling through these
stacks of images (ordered by image number) my app loads the pixel data
associated with that image. The user can be viewing the image series in
multiple windows. So each window can point to this one vector of images
so they dont each have to keep their own copy. This was working fine.
Now I run into the problem that my users want to be able to sort the
images by the position tag too. Great. So I tried doing the sort but I
get a crash, I guess cause my destructor automatically deletes the
pixel data pointer during the copy?
So I guess I have to rethink my whole design now. Two big questions:
1) the pPix member might be allocated as unsigned shorts, or unsigned
char, depending on the image type. That's why I did not use a vector of
BYTE etc. Is there a way I can use templating or something to be able
to allocate the space as either unsigned short or unsigned char
depending on the data type? Currently I was doing it like this:
pPix = (BYTE *)new unsigned short[cx * cy];
or
pPix = (BYTE *)new unsigned char[cx * cy];
this worked fine but was a little annoying when I had to access the
pixel data since I had to constantly check what it was allocated as and
cast it before touching it to get the right values.
2) I only want to have to keep one copy of my pixel data (since there
can be an awful lot). I was thinking of keeping one copy in something
like this:
map<string, map<string, set<PixelSink> > m_Dataset;
So it looks like this:
Study A (StudyID)
|
|---- Series 1A (SeriesID)
| | ---- Pixel Sink (just pixel data) (ImageID)
| | ---- Pixel Sink (just pixel data) (ImageID)
|
|---- Series 1B
| | ---- Pixel Sink (just pixel data) (ImageID)
|
|
Study B
| etc...
So in each window view I still keep a vector of IMAGE structs, but
remove the pPix member. When the user wants to sort by whatever tag
they want, I sort the vector with the new scheme, then can still look
up its associated pixel data by studyID, seriesID, imageID in the
global map.
Is that ridiculous? More information needed? Feel free to bash, I don't
want to have to rewrite this again! Thanks for any suggestions,
Mark