// **************************************************************************** // Method: avtImgCommunicator::rleEncodeAll // // Purpose: // Encodes an image using RLE: Runlength, R, G, B, A // // Arguments: // dimsX & dimsY : width & height of the image // imgArray : array containing all the division composited by this processor // numDivs : number of Z divisions // // encoding : the image compressed using RLE; it's a float so that it can be sent directly using MPI // sizeOfEncoding : the compressed size of each image // // // Programmer: Pascal Grosset // Creation: August 23, 2013 // // Modifications: // // **************************************************************************** int avtImgCommunicator::rleEncodeAll(int dimsX, int dimsY, int numDivs, float *imgArray, float *& encoding, int *& sizeOfEncoding){ std::vector<code> encodingVec; encodingVec.clear(); code tempCode; sizeOfEncoding = new int[numDivs]; int prev = 0; // Compress the data for (int j=0; j<numDivs; j++){ int offset = dimsX*dimsY*4 * j; // to get the next image in the array of images int i=0; tempCode = initCode(1, imgArray[offset + (i*4+0)],imgArray[offset + (i*4+1)],imgArray[offset + (i*4+2)], imgArray[offset + (i*4+3)]); for (i=1; i<dimsX*dimsY; i++){ if ( compareColor(tempCode, imgArray[offset + (i*4+0)],imgArray[offset + (i*4+1)],imgArray[offset + (i*4+2)],imgArray[offset + (i*4+3)]) ) tempCode = incrCode(tempCode); else{ encodingVec.push_back(tempCode); tempCode = initCode(1, imgArray[offset + (i*4+0)],imgArray[offset + (i*4+1)],imgArray[offset + (i*4+2)],imgArray[offset + (i*4+3)]); } } encodingVec.push_back(tempCode); if (j == 0) prev = sizeOfEncoding[j] = encodingVec.size(); else{ sizeOfEncoding[j] = encodingVec.size() - prev; prev = encodingVec.size(); } debug5 << my_id << " ~ encoding.size(): " << sizeOfEncoding[j] << " offset: " << offset << " original size: " << (dimsX * dimsY * 4) << " size: " << encodingVec.size() << std::endl; } // Transfer the data to the encoding array int encSize = encodingVec.size(); encoding = new float[encSize*5]; int index = 0; for (int j=0; j<encSize; j++){ encoding[index] = encodingVec[j].count; index++; encoding[index] = encodingVec[j].color[0]; index++; encoding[index] = encodingVec[j].color[1]; index++; encoding[index] = encodingVec[j].color[2]; index++; encoding[index] = encodingVec[j].color[3]; index++; } encodingVec.clear(); return encSize; // size of the array }
// Flood fill // ----- http://lodev.org/cgtutor/floodfill.html void BitmapImage::floodFill(BitmapImage* targetImage, QRect cameraRect, QPoint point, QRgb newColor, int tolerance) { // If the point we are supposed to fill is outside the image and camera bounds, do nothing if(!cameraRect.united(targetImage->bounds()).contains(point)) { return; } // Square tolerance for use with compareColor tolerance = static_cast<int>(qPow(tolerance, 2)); QRgb oldColor = targetImage->pixel(point); oldColor = qRgba(qRed(oldColor), qGreen(oldColor), qBlue(oldColor), qAlpha(oldColor)); // Preparations QList<QPoint> queue; // queue all the pixels of the filled area (as they are found) BitmapImage* replaceImage = nullptr; QPoint tempPoint; QRgb newPlacedColor = 0; QScopedPointer< QHash<QRgb, bool> > cache(new QHash<QRgb, bool>()); int xTemp = 0; bool spanLeft = false; bool spanRight = false; // Extend to size of Camera targetImage->extend(cameraRect); replaceImage = new BitmapImage(cameraRect, Qt::transparent); queue.append(point); // Preparations END while (!queue.empty()) { tempPoint = queue.takeFirst(); point.setX(tempPoint.x()); point.setY(tempPoint.y()); xTemp = point.x(); newPlacedColor = replaceImage->constScanLine(xTemp, point.y()); while (xTemp >= targetImage->mBounds.left() && compareColor(targetImage->constScanLine(xTemp, point.y()), oldColor, tolerance, cache.data())) xTemp--; xTemp++; spanLeft = spanRight = false; while (xTemp <= targetImage->mBounds.right() && compareColor(targetImage->constScanLine(xTemp, point.y()), oldColor, tolerance, cache.data()) && newPlacedColor != newColor) { // Set pixel color replaceImage->scanLine(xTemp, point.y(), newColor); if (!spanLeft && (point.y() > targetImage->mBounds.top()) && compareColor(targetImage->constScanLine(xTemp, point.y() - 1), oldColor, tolerance, cache.data())) { queue.append(QPoint(xTemp, point.y() - 1)); spanLeft = true; } else if (spanLeft && (point.y() > targetImage->mBounds.top()) && !compareColor(targetImage->constScanLine(xTemp, point.y() - 1), oldColor, tolerance, cache.data())) { spanLeft = false; } if (!spanRight && point.y() < targetImage->mBounds.bottom() && compareColor(targetImage->constScanLine(xTemp, point.y() + 1), oldColor, tolerance, cache.data())) { queue.append(QPoint(xTemp, point.y() + 1)); spanRight = true; } else if (spanRight && point.y() < targetImage->mBounds.bottom() && !compareColor(targetImage->constScanLine(xTemp, point.y() + 1), oldColor, tolerance, cache.data())) { spanRight = false; } Q_ASSERT(queue.count() < (targetImage->mBounds.width() * targetImage->mBounds.height())); xTemp++; } } targetImage->paste(replaceImage); targetImage->modification(); delete replaceImage; }