00001 #include "ImageData.h"
00002
00003 ImageData::ImageData (int bytesPerPixel)
00004 {
00005 m_bytesPerPixel = bytesPerPixel;
00006 m_size = 0;
00007 m_numDataLines = 0;
00008 m_clippedImage = NULL;
00009 m_clippedImageAllocated = false;
00010 m_startx = 0;
00011 m_starty = 0;
00012 m_sizex = 0;
00013 m_sizey = 0;
00014 m_header = NULL;
00015 m_headerSize = 0;
00016 }
00017
00018 ImageData::~ImageData ()
00019 {
00020 if (true == m_clippedImageAllocated)
00021 {
00022 delete [] m_clippedImage;
00023 }
00024
00025 if (NULL != m_header)
00026 {
00027 delete [] m_header;
00028 }
00029 }
00030
00031 void ImageData::WriteHeader(ImageDataCombine_t combine,
00032 const liveVizRequest* req,
00033 byte* dest)
00034 {
00035 ImageHeader *ihead=(ImageHeader *)dest;
00036 ihead->m_combine=combine;
00037
00038
00039 if(req)
00040 ihead->m_req=*req;
00041 }
00042
00043 void ImageData::ReadHeader(ImageDataCombine_t &combine,
00044 liveVizRequest* req,
00045 const byte* src)
00046 {
00047 const ImageHeader *ihead=(const ImageHeader *)src;
00048 combine=ihead->m_combine;
00049 *req=ihead->m_req;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 int ImageData::GetBuffSize (const int& startx,
00068 const int& starty,
00069 const int& sizex,
00070 const int& sizey,
00071 const int req_wid,
00072 const int req_ht,
00073 const byte* src)
00074 {
00075 GetClippedImage (src,
00076 startx,
00077 starty,
00078 sizex,
00079 sizey,
00080 req_wid,
00081 req_ht
00082 );
00083
00084 return AddImage (req_wid);
00085 }
00086
00087
00088 byte* ImageData::GetClippedImage (const byte* img,
00089 const int& startx,
00090 const int& starty,
00091 const int& sizex,
00092 const int& sizey,
00093 const int req_wid,
00094 const int req_ht
00095 )
00096 {
00097 bool shift = false;
00098 int newpos = 0;
00099 int oldpos = 0;
00100 int bytesPerRow = 0;
00101 int xoffset = 0;
00102
00103
00104 m_startx = startx;
00105 m_starty = starty;
00106 m_sizex = sizex;
00107 m_sizey = sizey;
00108 m_clippedImage = (byte*)img;
00109
00110 if (NULL == img)
00111 {
00112 goto EXITPOINT;
00113 }
00114
00115
00116 if (((startx+sizex-1) < 0) ||
00117 ((starty+sizey-1) < 0) ||
00118 (startx > (req_wid-1)) ||
00119 (starty > (req_ht-1)))
00120 {
00121 m_clippedImage = NULL;
00122 goto EXITPOINT;
00123 }
00124
00125 if (0 > starty)
00126 {
00127 m_clippedImage += (0-starty)*sizex*m_bytesPerPixel;
00128 m_sizey += starty;
00129 m_starty = 0;
00130 }
00131
00132 if ((m_starty+m_sizey) > req_ht)
00133 {
00134 m_sizey = req_ht - m_starty;
00135 }
00136
00137
00138 if (0 > startx)
00139 {
00140 m_sizex += startx;
00141 m_startx = 0;
00142 shift = true;
00143 }
00144
00145 if ((m_startx + m_sizex) > req_wid)
00146 {
00147 m_sizex = req_wid - m_startx;
00148 shift = true;
00149 }
00150
00151 if (true == shift)
00152 {
00153 int imgSize = m_sizex*m_sizey*m_bytesPerPixel;
00154
00155 m_clippedImage = new byte [imgSize];
00156
00157 if (NULL == m_clippedImage)
00158 {
00159
00160 CmiPrintf ("Memory allocation failure!!!\n");
00161 goto EXITPOINT;
00162 }
00163
00164 m_clippedImageAllocated = true;
00165
00166 xoffset = (m_startx - startx) * m_bytesPerPixel;
00167 bytesPerRow = m_sizex * m_bytesPerPixel;
00168
00169 for (int y=0; y<m_sizey; y++)
00170 {
00171 oldpos = (m_starty + y - starty)*sizex*m_bytesPerPixel + xoffset;
00172 for (int x=0; x<bytesPerRow; x++)
00173 {
00174 m_clippedImage [newpos ++] = img [oldpos ++];
00175 }
00176 }
00177 }
00178
00179 EXITPOINT:
00180 return m_clippedImage;
00181 }
00182
00183
00184 #ifdef COMPLETE_BLACK_PIXEL_ELIMINATION
00185
00186 int ImageData::AddImage (const int req_wid,
00187 byte* dest)
00188 {
00189 LineHeader head;
00190 int headPos = 0;
00191 int dataPos = 0;
00192 int pos = 0;
00193 int numOnPixels = 0;
00194
00195 int numDataLines = 0;
00196
00197 bool isPixelOn = false;
00198 bool foundLine = false;
00199
00200 const byte* src = m_clippedImage;
00201 const int startx = m_startx;
00202 const int starty = m_starty;
00203 const int sizex = m_sizex;
00204 const int sizey = m_sizey;
00205
00206 if (NULL != dest)
00207 {
00208
00209 headPos = sizeof (ImageHeader);
00210 dataPos = headPos + (sizeof (LineHeader) * m_numDataLines);
00211 ImageHeader *ihead=(ImageHeader *)dest;
00212 ihead->m_lines=m_numDataLines;
00213 }
00214
00215 if (NULL != src)
00216 {
00217 for (int y=0; y<sizey; y++)
00218 {
00219 for (int x=0; x<sizex; x++)
00220 {
00221 isPixelOn = IsPixelOn (src + pos);
00222
00223 if ((false == foundLine) && (true == isPixelOn))
00224 {
00225
00226 if (NULL != dest)
00227 {
00228 head.m_pos = ((starty + y)*(req_wid)) +
00229 (startx + x);
00230 head.m_size = 0;
00231 }
00232
00233 foundLine = true;
00234 }
00235
00236 if (true == isPixelOn)
00237 {
00238 if (NULL != dest)
00239 {
00240
00241 head.m_size ++;
00242
00243
00244 CopyPixel (dest+dataPos, src+pos);
00245
00246
00247 dataPos += m_bytesPerPixel;
00248 }
00249
00250 numOnPixels ++;
00251 }
00252 else
00253 {
00254 if (true == foundLine)
00255 {
00256
00257 if (NULL != dest)
00258 {
00259
00260 memcpy (dest + headPos,
00261 &head,
00262 sizeof (LineHeader));
00263
00264
00265 headPos += sizeof (LineHeader);
00266 }
00267
00268 numDataLines ++;
00269 foundLine = false;
00270 }
00271 }
00272
00273 pos += m_bytesPerPixel;
00274 }
00275
00276 if (true == foundLine)
00277 {
00278
00279 if (NULL != dest)
00280 {
00281
00282 memcpy (dest + headPos,
00283 &head,
00284 sizeof (LineHeader));
00285
00286
00287 headPos += sizeof (LineHeader);
00288 }
00289
00290 numDataLines ++;
00291 foundLine = false;
00292 }
00293 }
00294 }
00295
00296 SetSize(numDataLines,numOnPixels);
00297
00298 return m_size;
00299 }
00300
00301 #endif
00302
00303 #ifdef NO_BLACK_PIXEL_ELIMINATION
00304
00305 int ImageData::AddImage (const int req_wid
00306 byte* dest)
00307 {
00308 LineHeader head;
00309 int headPos = 0;
00310 int dataPos = 0;
00311 int pos = 0;
00312 int numOnPixels = 0;
00313
00314 int numDataLines = 0;
00315
00316 bool isPixelOn = false;
00317 bool foundLine = false;
00318
00319 const byte* src = m_clippedImage;
00320 const int startx = m_startx;
00321 const int starty = m_starty;
00322 const int sizex = m_sizex;
00323 const int sizey = m_sizey;
00324
00325 if (NULL != dest)
00326 {
00327
00328 headPos = sizeof (ImageHeader);
00329 dataPos = headPos + (sizeof (LineHeader) * m_numDataLines);
00330 ImageHeader *ihead=(ImageHeader *)dest;
00331 ihead->m_lines=m_numDataLines;
00332 }
00333
00334 if (NULL != src)
00335 {
00336 int bytesToCopy = sizex*m_bytesPerPixel;
00337
00338 for (int y=0; y<sizey; y++)
00339 {
00340 if (NULL != dest)
00341 {
00342 head.m_pos = ((starty + y)*(req_wid)) +
00343 (startx);
00344 head.m_size = sizex;
00345
00346
00347 memcpy (dest+dataPos, src+pos, bytesToCopy);
00348
00349 dataPos += bytesToCopy;
00350 pos += bytesToCopy;
00351
00352
00353 memcpy (dest + headPos,
00354 &head,
00355 sizeof (LineHeader));
00356
00357
00358 headPos += sizeof (LineHeader);
00359 }
00360
00361 numOnPixels += sizex;
00362 numDataLines ++;
00363 }
00364 }
00365
00366 SetSize(numDataLines,numOnPixels);
00367
00368 return m_size;
00369 }
00370 #endif
00371
00372 #ifdef EXTERIOR_BLACK_PIXEL_ELIMINATION
00373
00374
00375
00376
00377 int ImageData::AddImage (const int req_wid,
00378 byte* dest)
00379 {
00380 LineHeader head;
00381 int headPos = 0;
00382 int dataPos = 0;
00383 int numOnPixels = 0;
00384
00385 int numDataLines = 0;
00386
00387 bool isPixelOn = false;
00388 bool foundLine = false;
00389
00390 const int startx = m_startx;
00391 const int starty = m_starty;
00392 const int sizex = m_sizex;
00393 const int sizey = m_sizey;
00394
00395 if (NULL != dest)
00396 {
00397
00398 headPos = sizeof (ImageHeader);
00399 dataPos = headPos + (sizeof (LineHeader) * m_numDataLines);
00400 ImageHeader *ihead=(ImageHeader *)dest;
00401 ihead->m_lines=m_numDataLines;
00402 }
00403
00404 if (NULL != m_clippedImage)
00405 {
00406 for (int y=0; y<sizey; y++)
00407 {
00408 int startPos = y*sizex*m_bytesPerPixel;
00409 int endPos = startPos + (sizex-1)*m_bytesPerPixel;
00410 int xoffset = 0;
00411 int bytesToCopy = 0;
00412 bool startPixelFound = false;
00413 bool endPixelFound = false;
00414
00415 while (startPos <= endPos)
00416 {
00417 startPixelFound = IsPixelOn (m_clippedImage+startPos);
00418 endPixelFound = IsPixelOn (m_clippedImage+endPos);
00419
00420 if (false == startPixelFound)
00421 {
00422 startPos += m_bytesPerPixel;
00423 xoffset ++;
00424 }
00425
00426 if (false == endPixelFound)
00427 {
00428 endPos -= m_bytesPerPixel;
00429 }
00430
00431 if (startPixelFound && endPixelFound)
00432 {
00433 break;
00434 }
00435 }
00436
00437 if (startPos <= endPos)
00438 {
00439 numDataLines ++;
00440 numOnPixels += (endPos - startPos)/m_bytesPerPixel + 1;
00441
00442 if (NULL != dest)
00443 {
00444 head.m_pos = ((starty + y)*(req_wid)) +
00445 (startx + xoffset);
00446 head.m_size = (endPos - startPos)/m_bytesPerPixel + 1;
00447
00448 bytesToCopy = (head.m_size)*m_bytesPerPixel;
00449
00450
00451 memcpy (dest+dataPos, m_clippedImage+startPos, bytesToCopy);
00452
00453 dataPos += bytesToCopy;
00454
00455
00456 memcpy (dest + headPos,
00457 &head,
00458 sizeof (LineHeader));
00459
00460
00461 headPos += sizeof (LineHeader);
00462 }
00463 }
00464 }
00465 }
00466
00467 SetSize(numDataLines,numOnPixels);
00468
00469 return m_size;
00470 }
00471 #endif
00472
00473
00474
00475
00476
00477
00478 int ImageData::CombineImageDataSize (int nMsg, CkReductionMsg **msgs)
00479 {
00480 int returnVal = 0;
00481 int buffSize = 0;
00482 int headPos = 0;
00483 int numNonNullLists = 0;
00484
00485 int numDataLines = 0;
00486
00487 int numPixels = 0;
00488
00489
00490 int minIndex = 0;
00491
00492
00493 int minPos = 0;
00494
00495 int minSize = 0;
00496 int currPos = 0;
00497
00498 int currSize = 0;
00499 int* pos = NULL;
00500
00501 int* size = NULL;
00502 byte* buff = NULL;
00503 LineHeader* prevHead = NULL;
00504
00505 LineHeader* currHead = NULL;
00506 LineHeader* minHead = NULL;
00507
00508 int i;
00509
00516 buffSize += sizeof (ImageHeader);
00517
00518
00519 for (i=0; i<nMsg; i++)
00520 {
00521 buffSize += ((ImageHeader *)(msgs [i]->getData ()))->m_lines*sizeof (LineHeader);
00522 }
00523
00524
00525 buffSize += sizeof (int) * nMsg * 2;
00526
00527
00528
00529 buff = new byte [buffSize];
00530
00531
00532 pos = (int*)(buff + buffSize - (sizeof (int)*nMsg*2));
00533 size = pos + nMsg;
00534
00535
00536
00537 headPos = sizeof (ImageHeader);
00538
00539
00540 for (i=0; i<nMsg; i++)
00541 {
00542 size [i] = ((ImageHeader *)(msgs[i])->getData ())->m_lines;
00543 pos [i] = 0;
00544 }
00545
00546
00547 numNonNullLists = NumNonNullLists (pos, size, nMsg);
00548
00549
00550
00551 while (1 < numNonNullLists)
00552 {
00553
00554 minIndex = GetNonNullListIndex (pos, nMsg);
00555
00556
00557 minHead = getHeader(msgs[minIndex]->getData (), pos [minIndex]);
00558
00559
00560 minPos = minHead->m_pos;
00561 minSize = minHead->m_size;
00562
00563
00564 for (int i=minIndex+1; i<nMsg; i++)
00565 {
00566 if (-1 != pos [i])
00567 {
00568
00569
00570 currHead = getHeader(msgs [i]->getData (),pos [i]);
00571
00572 currPos = currHead->m_pos;
00573 currSize = currHead->m_size;
00574
00575 if (minPos > currPos)
00576 {
00577 minHead = currHead;
00578 minIndex = i;
00579 minPos = currPos;
00580 minSize = currSize;
00581 }
00582 }
00583 }
00584
00585
00586 pos [minIndex] ++;
00587
00588
00589
00590
00591 if ((NULL != prevHead) &&
00592 ((prevHead->m_pos + prevHead->m_size) >= minPos))
00593 {
00594
00595 if ((minPos + minSize) > (prevHead->m_pos + prevHead->m_size))
00596 {
00597 numPixels -= prevHead->m_size;
00598 prevHead->m_size = minPos - prevHead->m_pos + minSize;
00599 numPixels += prevHead->m_size;
00600 }
00601 }
00602 else
00603 {
00604 prevHead = (LineHeader*)(buff + headPos);
00605 memcpy ((void*) prevHead,
00606 (void*) minHead,
00607 sizeof (LineHeader));
00608 headPos += sizeof (LineHeader);
00609 numDataLines ++;
00610 numPixels += prevHead->m_size;
00611 }
00612
00613
00614 numNonNullLists = NumNonNullLists (pos, size, nMsg);
00615 }
00616
00617 if (0 < numNonNullLists)
00618 {
00619
00620 minIndex = GetNonNullListIndex (pos, nMsg);
00621
00622
00623 minHead = getHeader(msgs [minIndex]->getData (), pos [minIndex]);
00624
00625 if (-1 != minIndex)
00626 {
00627 for (int i=pos [minIndex]; i<size [minIndex]; i++)
00628 {
00629 minPos = minHead->m_pos;
00630 minSize = minHead->m_size;
00631
00632 if ((NULL != prevHead) &&
00633 ((prevHead->m_pos + prevHead->m_size) >= minPos))
00634 {
00635 if ((minPos + minSize) > (prevHead->m_pos + prevHead->m_size))
00636 {
00637 numPixels -= prevHead->m_size;
00638 prevHead->m_size = minPos - prevHead->m_pos + minSize;
00639 numPixels += prevHead->m_size;
00640 }
00641
00642 minHead ++;
00643 }
00644 else
00645 {
00646 prevHead = (LineHeader*)(buff + headPos);
00647 memcpy ((void*)prevHead, (void*)minHead, sizeof (LineHeader));
00648 numPixels += ((LineHeader*)(buff+headPos))->m_size;
00649 headPos += sizeof (LineHeader);
00650 minHead ++;
00651 numDataLines ++;
00652 }
00653 }
00654 }
00655 }
00656
00657
00658
00659 m_header=buff;
00660 memcpy (m_header,
00661 msgs[0]->getData (),
00662 sizeof (ImageHeader));
00663 ((ImageHeader *)m_header)->m_lines=numDataLines;
00664
00665 SetSize(numDataLines,numPixels);
00666 returnVal = m_size;
00667
00668 EXITPOINT:
00669 return returnVal;
00670 }
00671
00672 void ImageData::CombineImageData (int nMsg, CkReductionMsg **msgs, byte* dest)
00673 {
00674
00675 memcpy (dest, m_header, m_headerSize);
00676
00677
00678 memset (dest+m_headerSize, 0, m_size-m_headerSize);
00679
00680
00681 for (int i=0; i<nMsg; i++)
00682 {
00683 CopyImageData (dest, m_numDataLines, msgs[i],
00684 ((ImageHeader *)dest)->m_combine);
00685 }
00686 }
00687
00688
00689 template<class T>
00690 inline void maxArrayT(const T *in,T *out,int n)
00691 {
00692 for (int i=0;i<n;i++)
00693 if (in[i]>out[i]) out[i]=in[i];
00694 }
00695 template<class T>
00696 inline void sumArrayT(const T *in,T *out,int n)
00697 {
00698 for (int i=0;i<n;i++)
00699 out[i]+=in[i];
00700 }
00701 template<class T,class C>
00702 inline void sumArrayClipT(const T *in,T *out,int n,C c)
00703 {
00704 for (int i=0;i<n;i++) {
00705 C sum=out[i];
00706 sum+=in[i];
00707 if (sum>c) sum=c;
00708 out[i]=(T)sum;
00709 }
00710 }
00711
00712 int ImageData::CopyImageData (byte* dest,
00713 int n,
00714 const CkReductionMsg* msg,
00715 ImageDataCombine_t reducer)
00716 {
00717 int returnVal = 0;
00718 int destHeadPos = 0;
00719 int destDataPos = 0;
00720 int srcDataPos = 0;
00721 int srcHeadPos = 0;
00722 int numSrcDataLines = 0;
00723 int bytesToCopy = 0;
00724 const byte* src = (const byte*)(msg->getData());
00725 LineHeader* destLineHeader = NULL;
00726 const LineHeader* srcLineHeader = NULL;
00727
00728 numSrcDataLines = ((ImageHeader*)src)->m_lines;
00729
00730 destHeadPos = sizeof (ImageHeader);
00731 srcHeadPos = sizeof (ImageHeader);
00732 destDataPos = destHeadPos + (sizeof (LineHeader) * n);
00733 srcDataPos = srcHeadPos + (sizeof (LineHeader) * numSrcDataLines);
00734
00735 destLineHeader = (LineHeader*)(dest + destHeadPos);
00736 srcLineHeader = (const LineHeader*)(src + srcHeadPos);
00737
00738 for (int i=0; i<numSrcDataLines; i++)
00739 {
00740
00741 while ((destLineHeader->m_pos +
00742 destLineHeader->m_size - 1) < srcLineHeader->m_pos)
00743 {
00744 destDataPos += (m_bytesPerPixel*(destLineHeader->m_size));
00745 destLineHeader++;
00746 }
00747
00748
00749 bytesToCopy = m_bytesPerPixel * (srcLineHeader->m_size);
00750 int posInDataLine = (srcLineHeader->m_pos -
00751 destLineHeader->m_pos) * m_bytesPerPixel;
00752 const byte *srcRow=src + srcDataPos;
00753 byte *destRow=dest + destDataPos + posInDataLine;
00754
00755 switch(reducer) {
00756 case sum_image_data:
00757 sumArrayClipT(srcRow,destRow,bytesToCopy, 0xff);
00758 break;
00759 case max_image_data:
00760 maxArrayT(srcRow,destRow,bytesToCopy);
00761 break;
00762 case sum_float_image_data:
00763 sumArrayT((const float *)srcRow,(float *)destRow,bytesToCopy/sizeof(float));
00764 break;
00765 case max_float_image_data:
00766 maxArrayT((const float *)srcRow,(float *)destRow,bytesToCopy/sizeof(float));
00767 break;
00768 default:
00769 CkAbort("LiveViz ImageData: Unrecognized image reducer type!\n");
00770 }
00771 srcLineHeader++;
00772 srcDataPos+=bytesToCopy;
00773 }
00774
00775 return returnVal;
00776 }
00777
00778
00779
00780
00781
00782
00783 byte* ImageData::ConstructImage (byte* src,
00784 liveVizRequest& req)
00785 {
00786 int i;
00787 int numDataLines = 0;
00788 int headPos = 0;
00789 int dataPos = 0;
00790 int imageSize = 0;
00791 int imagePos = 0;
00792 int numBytesToCopy = 0;
00793 byte* image = NULL;
00794 const ImageHeader *ihead = (const ImageHeader *)src;
00795 LineHeader* head = NULL;
00796
00797 numDataLines = ihead->m_lines;
00798 req=ihead->m_req;
00799
00800 headPos = sizeof (ImageHeader);
00801 dataPos = headPos + (sizeof (LineHeader) * numDataLines);
00802
00803 imageSize = req.wid*req.ht*m_bytesPerPixel;
00804
00805 image = new byte [imageSize];
00806
00807 if (NULL == image)
00808 {
00809 goto EXITPOINT;
00810 }
00811
00812 memset (image, 0, imageSize);
00813
00814 head = (LineHeader*) (src + headPos);
00815
00816 for (i=0; i<numDataLines; i++)
00817 {
00818 numBytesToCopy = head->m_size*m_bytesPerPixel;
00819 imagePos = head->m_pos*m_bytesPerPixel;
00820
00821 memcpy (image+imagePos, src+dataPos, numBytesToCopy);
00822 dataPos += numBytesToCopy;
00823 head ++;
00824 }
00825
00826 EXITPOINT:
00827 return image;
00828 }