void ofPixels_<PixelType>::rotate90(int nClockwiseRotations){ int channels = channelsFromPixelFormat(pixelFormat); if (bAllocated == false || channels==0){ return; } // first, figure out which type of rotation we have int rotation = nClockwiseRotations; while (rotation < 0){ rotation+=4; } rotation %= 4; // if it's 0, do nothing. if it's 2, do it by a mirror operation. if (rotation == 0) { return; // do nothing! } else if (rotation == 2) { mirror(true, true); return; } ofPixels_<PixelType> newPixels; rotate90To(newPixels,nClockwiseRotations); std::swap(newPixels.pixels,pixels); width = newPixels.width; height = newPixels.height; pixelsSize = newPixels.size(); }
void ofPixels_<PixelType>::setChannel(int channel, const ofPixels_<PixelType> channelPixels){ int channels = channelsFromPixelFormat(pixelFormat); if(channels==0) return; channel = ofClamp(channel,0,channels-1); const_iterator channelPixel = channelPixels.begin(); for(auto p: getPixelsIter()){ p[channel] = *channelPixel++; } }
void ofPixels_<PixelType>::setChannel(int channel, const ofPixels_<PixelType> channelPixels){ int channels = channelsFromPixelFormat(pixelFormat); if(channels==0) return; channel = ofClamp(channel,0,channels-1); const_iterator channelPixel = channelPixels.begin(); iterator _end = end(); for(iterator i=begin()+channel;i<_end;i+=channels,++channelPixel){ *i = *channelPixel; } }
void ofPixels_<PixelType>::setFromAlignedPixels(const PixelType * newPixels, int width, int height, ofPixelFormat _pixelFormat, std::vector<int> strides) { int channels = channelsFromPixelFormat(_pixelFormat); if(channels==0) return; switch(pixelFormat){ case OF_PIXELS_I420: { if(strides.size() != 3){ ofLogError("ofPixels") << "number of planes for I420 should be 3"; break; } if(width==strides[0] && width/2==strides[1] && width/2==strides[2]){ setFromPixels(newPixels,width,height,_pixelFormat); return; } allocate(width, height, _pixelFormat); const unsigned char* src = (unsigned char*) newPixels; unsigned char* dst = (unsigned char*) pixels; // Y Plane for(int i = 0; i < height; i++) { memcpy(dst, src, width); src += strides[0]; dst += width; } // U Plane for(int i = 0; i < height /2; i++){ memcpy(dst,src,width/2); src += strides[1]; dst += width/2; } // V Plane for(int i = 0; i < height /2; i++){ memcpy(dst,src,width/2); src += strides[2]; dst += width/2; } break; } case OF_PIXELS_RGB: case OF_PIXELS_RGBA: case OF_PIXELS_GRAY: case OF_PIXELS_GRAY_ALPHA: setFromAlignedPixels(newPixels,width,height,_pixelFormat,strides[0]); return; default: ofLogError("ofPixels") << "setFromAlignedPixels with planes strides: pixel format not supported yet"; break; } return; }
ofPixels_<PixelType> ofPixels_<PixelType>::getChannel(int channel) const{ ofPixels_<PixelType> channelPixels; int channels = channelsFromPixelFormat(pixelFormat); if(channels==0) return channelPixels; channelPixels.allocate(width,height,1); channel = ofClamp(channel,0,channels-1); iterator channelPixel = channelPixels.begin(); for(auto p: getConstPixelsIter()){ *channelPixel++ = p[channel]; } return std::move(channelPixels); }
ofPixels_<PixelType> ofPixels_<PixelType>::getChannel(int channel) const{ ofPixels_<PixelType> channelPixels; int channels = channelsFromPixelFormat(pixelFormat); if(channels==0) return channelPixels; channelPixels.allocate(width,height,1); channel = ofClamp(channel,0,channels-1); iterator channelPixel = channelPixels.begin(); const_iterator _end = end(); for(const_iterator i=begin()+channel;i<_end;i+=channels,++channelPixel){ *channelPixel = *i; } return channelPixels; }
void ofPixels_<PixelType>::setFromAlignedPixels(const PixelType * newPixels, int width, int height, ofPixelFormat _pixelFormat, int stride) { int channels = channelsFromPixelFormat(_pixelFormat); if(channels==0) return; if(width*channels==stride){ setFromPixels(newPixels,width,height,_pixelFormat); return; } allocate(width, height, _pixelFormat); int dstStride = width * pixelBytesFromPixelFormat<PixelType>(_pixelFormat); const unsigned char* src = (unsigned char*) newPixels; unsigned char* dst = (unsigned char*) pixels; for(int i = 0; i < height; i++) { memcpy(dst, src, dstStride); src += stride; dst += dstStride; } }
void ofPixels_<PixelType>::mirror(bool vertically, bool horizontal){ int channels = channelsFromPixelFormat(pixelFormat); if ((!vertically && !horizontal) || channels==0){ return; } int bytesPerPixel = channels; PixelType * oldPixels = pixels; PixelType tempVal; if (! (vertically && horizontal)){ int wToDo = horizontal ? width/2 : width; int hToDo = vertically ? height/2 : height; for (int i = 0; i < wToDo; i++){ for (int j = 0; j < hToDo; j++){ int pixelb = (vertically ? (height - j - 1) : j) * width + (horizontal ? (width - i - 1) : i); int pixela = j*width + i; for (int k = 0; k < bytesPerPixel; k++){ tempVal = oldPixels[pixela*bytesPerPixel + k]; oldPixels[pixela*bytesPerPixel + k] = oldPixels[pixelb*bytesPerPixel + k]; oldPixels[pixelb*bytesPerPixel + k] = tempVal; } } } } else { // I couldn't think of a good way to do this in place. I'm sure there is. mirror(true, false); mirror(false, true); } }
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; } } } }
int ofPixels_<PixelType>::getNumChannels() const{ return channelsFromPixelFormat(pixelFormat); }