void ofPixels_<PixelType>::cropTo(ofPixels_<PixelType> &toPix, int x, int y, int _width, int _height) const{ if (bAllocated){ if(&toPix == this){ toPix.crop(x,y,_width,_height); return; } _width = ofClamp(_width,1,getWidth()); _height = ofClamp(_height,1,getHeight()); if ((toPix.width != _width) || (toPix.height != _height) || (toPix.pixelFormat != pixelFormat)){ toPix.allocate(_width, _height, pixelFormat); } // this prevents having to do a check for bounds in the for loop; int minX = MAX(x, 0) * getNumChannels(); int maxX = MIN(x+_width, width) * getNumChannels(); int minY = MAX(y, 0); int maxY = MIN(y+_height, height); iterator newPixel = toPix.begin(); for(ConstLine line = getConstLines().begin()+minY; line!=getConstLines().begin()+maxY; ++line ){ for(const_iterator pixel = line.begin()+minX; pixel<line.begin()+maxX; ++pixel){ *newPixel++ = *pixel; } } } }
void ofPixels_<PixelType>::cropTo(ofPixels_<PixelType> &toPix, int x, int y, int _width, int _height) const{ if (bAllocated){ if(&toPix == this){ toPix.crop(x,y,_width,_height); return; } _width = ofClamp(_width,1,getWidth()); _height = ofClamp(_height,1,getHeight()); if ((toPix.width != _width) || (toPix.height != _height) || (toPix.pixelFormat != pixelFormat)){ toPix.allocate(_width, _height, pixelFormat); } // this prevents having to do a check for bounds in the for loop; int minX = MAX(x, 0); int maxX = MIN(x+_width, width); int minY = MAX(y, 0); int maxY = MIN(y+_height, height); auto newPixel = toPix.getPixelsIter().begin(); for(auto line: getConstLines(minY, maxY - minY)){ for(auto pixel: line.getPixels(minX, maxX - minX)){ newPixel++ = pixel; } } } }
bool ofPixels_<PixelType>::blendInto(ofPixels_<PixelType> &dst, int xTo, int yTo) const{ if (!(isAllocated()) || !(dst.isAllocated()) || getBytesPerPixel() != dst.getBytesPerPixel() || xTo + getWidth()>dst.getWidth() || yTo + getHeight()>dst.getHeight() || getNumChannels()==0) return false; std::function<void(const ConstPixel&,Pixel&)> blendFunc; switch(getNumChannels()){ case 1: blendFunc = [](const ConstPixel&src, Pixel&dst){ dst[0] = clampedAdd(src[0], dst[0]); }; break; case 2: blendFunc = [](const ConstPixel&src, Pixel&dst){ dst[0] = clampedAdd(src[0], dst[0] / ofColor_<PixelType>::limit() * (ofColor_<PixelType>::limit() - src[1])); dst[1] = clampedAdd(src[1], dst[1] / ofColor_<PixelType>::limit() * (ofColor_<PixelType>::limit() - src[1])); }; break; case 3: blendFunc = [](const ConstPixel&src, Pixel&dst){ dst[0] = clampedAdd(src[0], dst[0]); dst[1] = clampedAdd(src[1], dst[1]); dst[2] = clampedAdd(src[2], dst[2]); }; break; case 4: blendFunc = [](const ConstPixel&src, Pixel&dst){ dst[0] = clampedAdd(src[0], dst[0] / ofColor_<PixelType>::limit() * (ofColor_<PixelType>::limit() - src[3])); dst[1] = clampedAdd(src[1], dst[1] / ofColor_<PixelType>::limit() * (ofColor_<PixelType>::limit() - src[3])); dst[2] = clampedAdd(src[2], dst[2] / ofColor_<PixelType>::limit() * (ofColor_<PixelType>::limit() - src[3])); dst[3] = clampedAdd(src[3], dst[3] / ofColor_<PixelType>::limit() * (ofColor_<PixelType>::limit() - src[3])); }; break; } auto dstLine = dst.getLine(yTo); for(auto line: getConstLines()){ auto dstPixel = dstLine.getPixels().begin() + xTo; for(auto p: line.getPixels()){ blendFunc(p,dstPixel); dstPixel++; } dstLine++; } return true; }
void ofPixels_<PixelType>::mirrorTo(ofPixels_<PixelType> & dst, bool vertically, bool horizontal) const{ if(&dst == this){ dst.mirror(vertically,horizontal); return; } if (!vertically && !horizontal){ dst = *this; return; } int bytesPerPixel = getNumChannels(); dst.allocate(width, height, getPixelFormat()); if(vertically && !horizontal){ auto dstLines = dst.getLines(); auto lineSrc = getConstLines().begin(); auto line = --dstLines.end(); auto stride = line.getStride(); for(; line>=dstLines.begin(); --line, ++lineSrc){ memcpy(line.begin(), lineSrc.begin(), stride); } }else if (!vertically && horizontal){ int wToDo = width/2; int hToDo = height; for (int i = 0; i < wToDo; i++){ for (int j = 0; j < hToDo; j++){ int pixelb = i; int pixela = j*width + i; for (int k = 0; k < bytesPerPixel; k++){ dst[pixela*bytesPerPixel + k] = pixels[pixelb*bytesPerPixel + k]; dst[pixelb*bytesPerPixel + k] = pixels[pixela*bytesPerPixel + k]; } } } } else { // I couldn't think of a good way to do this in place. I'm sure there is. mirrorTo(dst,true, false); dst.mirror(false, true); } }