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; } } } }
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); } }
void ofPixels_<PixelType>::cropTo(ofPixels_<PixelType> &toPix, int x, int y, int _width, int _height){ if (bAllocated == true){ _width = ofClamp(_width,1,getWidth()); _height = ofClamp(_height,1,getHeight()); int bytesPerPixel = channels; if ((toPix.width != _width) || (toPix.height != _height) || (toPix.channels != channels)){ toPix.allocate(_width, _height, channels); } int newWidth = _width; PixelType * newPixels = toPix.pixels; // 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); // TODO: point math can help speed this up: for (int i = minX; i < maxX; i++){ for (int j = minY; j < maxY; j++){ int newPixel = (j-y) * newWidth + (i-x); int oldPixel = (j) * width + (i); for (int k = 0; k < bytesPerPixel; k++){ newPixels[newPixel*bytesPerPixel + k] = pixels[oldPixel*bytesPerPixel + k]; } } } } }
void ofPixels_<PixelType>::rotate90To(ofPixels_<PixelType> & dst, int nClockwiseRotations) const{ int channels = channelsFromPixelFormat(pixelFormat); if (bAllocated == false || channels==0){ return; } if(&dst == this){ dst.rotate90(nClockwiseRotations); return; } // first, figure out which type of rotation we have int rotation = nClockwiseRotations; while (rotation < 0){ rotation+=4; } rotation %= 4; // if it's 0, just make a copy. if it's 2, do it by a mirror operation. if (rotation == 0) { dst = *this; return; // do nothing! } else if (rotation == 2) { mirrorTo(dst, true, true); return; } // otherwise, we will need to do some new allocaiton. dst.allocate(height,width,getImageType()); int strideSrc = width * channels; int strideDst = dst.width * channels; if(rotation == 1){ PixelType * srcPixels = pixels; PixelType * startPixels = dst.getData() + strideDst; for (int i = 0; i < height; ++i){ startPixels -= channels; PixelType * dstPixels = startPixels; for (int j = 0; j < width; ++j){ for (int k = 0; k < channels; ++k){ dstPixels[k] = srcPixels[k]; } srcPixels += channels; dstPixels += strideDst; } } } else if(rotation == 3){ PixelType * dstPixels = dst.pixels; PixelType * startPixels = pixels + strideSrc; for (int i = 0; i < dst.height; ++i){ startPixels -= channels; PixelType * srcPixels = startPixels; for (int j = 0; j < dst.width; ++j){ for (int k = 0; k < channels; ++k){ dstPixels[k] = srcPixels[k]; } srcPixels += strideSrc; dstPixels += channels; } } } }