virtual void imageRect(const Rect& r, void* pixels) = 0; | virtual void imageRect(const Rect& r, void* pixels) = 0; | ||||
virtual void copyRect(const Rect& r, int srcX, int srcY) = 0; | virtual void copyRect(const Rect& r, int srcX, int srcY) = 0; | ||||
virtual rdr::U8* getRawPixelsRW(const Rect& r, int* stride) = 0; | |||||
virtual void releaseRawPixels(const Rect& r) = 0; | |||||
virtual rdr::U8* getRawBufferRW(const Rect& r, int* stride) = 0; | |||||
virtual void releaseRawBuffer(const Rect& r) = 0; | |||||
virtual const PixelFormat &getPreferredPF(void) = 0; | virtual const PixelFormat &getPreferredPF(void) = 0; | ||||
for (int y=0; y<fb->height(); y+=BLOCK_SIZE) { | for (int y=0; y<fb->height(); y+=BLOCK_SIZE) { | ||||
Rect pos(0, y, fb->width(), __rfbmin(fb->height(), y+BLOCK_SIZE)); | Rect pos(0, y, fb->width(), __rfbmin(fb->height(), y+BLOCK_SIZE)); | ||||
int srcStride; | int srcStride; | ||||
const rdr::U8* srcData = fb->getPixelsR(pos, &srcStride); | |||||
const rdr::U8* srcData = fb->getBuffer(pos, &srcStride); | |||||
oldFb.imageRect(pos, srcData, srcStride); | oldFb.imageRect(pos, srcData, srcStride); | ||||
} | } | ||||
int bytesPerPixel = fb->getPF().bpp/8; | int bytesPerPixel = fb->getPF().bpp/8; | ||||
int oldStride; | int oldStride; | ||||
rdr::U8* oldData = oldFb.getPixelsRW(r, &oldStride); | |||||
rdr::U8* oldData = oldFb.getBufferRW(r, &oldStride); | |||||
int oldStrideBytes = oldStride * bytesPerPixel; | int oldStrideBytes = oldStride * bytesPerPixel; | ||||
std::vector<Rect> changedBlocks; | std::vector<Rect> changedBlocks; | ||||
// Get a strip of the source buffer | // Get a strip of the source buffer | ||||
Rect pos(r.tl.x, blockTop, r.br.x, __rfbmin(r.br.y, blockTop+BLOCK_SIZE)); | Rect pos(r.tl.x, blockTop, r.br.x, __rfbmin(r.br.y, blockTop+BLOCK_SIZE)); | ||||
int fbStride; | int fbStride; | ||||
const rdr::U8* newBlockPtr = fb->getPixelsR(pos, &fbStride); | |||||
const rdr::U8* newBlockPtr = fb->getBuffer(pos, &fbStride); | |||||
int newStrideBytes = fbStride * bytesPerPixel; | int newStrideBytes = fbStride * bytesPerPixel; | ||||
rdr::U8* oldBlockPtr = oldData; | rdr::U8* oldBlockPtr = oldData; |
void | void | ||||
PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) { | PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) { | ||||
int inStride; | int inStride; | ||||
const U8* data = getPixelsR(r, &inStride); | |||||
const U8* data = getBuffer(r, &inStride); | |||||
// We assume that the specified rectangle is pre-clipped to the buffer | // We assume that the specified rectangle is pre-clipped to the buffer | ||||
int bytesPerPixel = format.bpp/8; | int bytesPerPixel = format.bpp/8; | ||||
int inBytesPerRow = inStride * bytesPerPixel; | int inBytesPerRow = inStride * bytesPerPixel; | ||||
int FullFramePixelBuffer::getStride() const { return width(); } | int FullFramePixelBuffer::getStride() const { return width(); } | ||||
rdr::U8* FullFramePixelBuffer::getPixelsRW(const Rect& r, int* stride) | |||||
rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride) | |||||
{ | { | ||||
*stride = getStride(); | *stride = getStride(); | ||||
return &data[(r.tl.x + (r.tl.y * *stride)) * format.bpp/8]; | return &data[(r.tl.x + (r.tl.y * *stride)) * format.bpp/8]; | ||||
void FullFramePixelBuffer::fillRect(const Rect& r, Pixel pix) { | void FullFramePixelBuffer::fillRect(const Rect& r, Pixel pix) { | ||||
int stride; | int stride; | ||||
U8 *buf = getPixelsRW(r, &stride); | |||||
U8 *buf = getBufferRW(r, &stride); | |||||
fillRectFn(buf, stride, r, pix); | fillRectFn(buf, stride, r, pix); | ||||
} | } | ||||
void FullFramePixelBuffer::imageRect(const Rect& r, const void* pixels, int srcStride) { | void FullFramePixelBuffer::imageRect(const Rect& r, const void* pixels, int srcStride) { | ||||
int bytesPerPixel = getPF().bpp/8; | int bytesPerPixel = getPF().bpp/8; | ||||
int destStride; | int destStride; | ||||
U8* dest = getPixelsRW(r, &destStride); | |||||
U8* dest = getBufferRW(r, &destStride); | |||||
int bytesPerDestRow = bytesPerPixel * destStride; | int bytesPerDestRow = bytesPerPixel * destStride; | ||||
if (!srcStride) srcStride = r.width(); | if (!srcStride) srcStride = r.width(); | ||||
int bytesPerSrcRow = bytesPerPixel * srcStride; | int bytesPerSrcRow = bytesPerPixel * srcStride; | ||||
Rect cr = getRect().intersect(r); | Rect cr = getRect().intersect(r); | ||||
if (cr.is_empty()) return; | if (cr.is_empty()) return; | ||||
int stride; | int stride; | ||||
U8* data = getPixelsRW(cr, &stride); | |||||
U8* data = getBufferRW(cr, &stride); | |||||
U8* mask = (U8*) mask_; | U8* mask = (U8*) mask_; | ||||
int w = cr.width(); | int w = cr.width(); | ||||
int h = cr.height(); | int h = cr.height(); | ||||
Rect cr = getRect().intersect(r); | Rect cr = getRect().intersect(r); | ||||
if (cr.is_empty()) return; | if (cr.is_empty()) return; | ||||
int stride; | int stride; | ||||
U8* data = getPixelsRW(cr, &stride); | |||||
U8* data = getBufferRW(cr, &stride); | |||||
U8* mask = (U8*) mask_; | U8* mask = (U8*) mask_; | ||||
int w = cr.width(); | int w = cr.width(); | ||||
int h = cr.height(); | int h = cr.height(); | ||||
if (srect.is_empty()) | if (srect.is_empty()) | ||||
return; | return; | ||||
data = getPixelsRW(getRect(), &stride); | |||||
data = getBufferRW(getRect(), &stride); | |||||
bytesPerPixel = getPF().bpp/8; | bytesPerPixel = getPF().bpp/8; | ||||
bytesPerRow = stride * bytesPerPixel; | bytesPerRow = stride * bytesPerPixel; | ||||
bytesPerMemCpy = drect.width() * bytesPerPixel; | bytesPerMemCpy = drect.width() * bytesPerPixel; |
// Get a pointer into the buffer | // Get a pointer into the buffer | ||||
// The pointer is to the top-left pixel of the specified Rect. | // The pointer is to the top-left pixel of the specified Rect. | ||||
// The buffer stride (in pixels) is returned. | // The buffer stride (in pixels) is returned. | ||||
virtual const rdr::U8* getPixelsR(const Rect& r, int* stride) = 0; | |||||
virtual rdr::U8* getPixelsRW(const Rect& r, int* stride) = 0; | |||||
virtual const rdr::U8* getBuffer(const Rect& r, int* stride) = 0; | |||||
virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0; | |||||
// Get pixel data for a given part of the buffer | // Get pixel data for a given part of the buffer | ||||
// Data is copied into the supplied buffer, with the specified | // Data is copied into the supplied buffer, with the specified | ||||
virtual int getStride() const; | virtual int getStride() const; | ||||
// Get a pointer to specified pixel data | // Get a pointer to specified pixel data | ||||
rdr::U8* getPixelsRW(const Rect& r, int* stride); | |||||
virtual const rdr::U8* getPixelsR(const Rect& r, int* stride) { | |||||
return getPixelsRW(r, stride); | |||||
virtual const rdr::U8* getBuffer(const Rect& r, int* stride) { | |||||
return getBufferRW(r, stride); | |||||
} | } | ||||
virtual rdr::U8* getBufferRW(const Rect& r, int* stride); | |||||
/////////////////////////////////////////////// | /////////////////////////////////////////////// | ||||
// Basic rendering operations | // Basic rendering operations |
PixelTransformer::setColourMapEntries(firstCol, nCols); | PixelTransformer::setColourMapEntries(firstCol, nCols); | ||||
} | } | ||||
const rdr::U8 *TransImageGetter::getRawPixelsR(const Rect &r, int *stride) | |||||
const rdr::U8 *TransImageGetter::getRawBufferR(const Rect &r, int *stride) | |||||
{ | { | ||||
if (!offset.equals(Point(0, 0))) | if (!offset.equals(Point(0, 0))) | ||||
return pb->getPixelsR(r.translate(offset.negate()), stride); | |||||
return pb->getBuffer(r.translate(offset.negate()), stride); | |||||
else | else | ||||
return pb->getPixelsR(r, stride); | |||||
return pb->getBuffer(r, stride); | |||||
} | } | ||||
void TransImageGetter::getImage(void* outPtr, const Rect& r, int outStride) | void TransImageGetter::getImage(void* outPtr, const Rect& r, int outStride) | ||||
{ | { | ||||
int inStride; | int inStride; | ||||
const rdr::U8* inPtr = pb->getPixelsR(r.translate(offset.negate()), &inStride); | |||||
const rdr::U8* inPtr = pb->getBuffer(r.translate(offset.negate()), &inStride); | |||||
if (!outStride) outStride = r.width(); | if (!outStride) outStride = r.width(); | ||||
// padding will be outStride-r.width() pixels). | // padding will be outStride-r.width() pixels). | ||||
void getImage(void* outPtr, const Rect& r, int outStride=0); | void getImage(void* outPtr, const Rect& r, int outStride=0); | ||||
// getRawPixelsR() gets the given rectangle of data directly from the | |||||
// getRawBufferR() gets the given rectangle of data directly from the | |||||
// underlying PixelBuffer, bypassing the translation logic. Only use | // underlying PixelBuffer, bypassing the translation logic. Only use | ||||
// this when doing something that's independent of the client's pixel | // this when doing something that's independent of the client's pixel | ||||
// format. | // format. | ||||
const rdr::U8 *getRawPixelsR(const Rect &r, int *stride); | |||||
const rdr::U8 *getRawBufferR(const Rect &r, int *stride); | |||||
// setPixelBuffer() changes the pixel buffer to be used. The new pixel | // setPixelBuffer() changes the pixel buffer to be used. The new pixel | ||||
// buffer MUST have the same pixel format as the old one - if not you | // buffer MUST have the same pixel format as the old one - if not you |
PIXEL_T *buf; | PIXEL_T *buf; | ||||
int stride = r.width(); | int stride = r.width(); | ||||
if (directDecode) buf = (PIXEL_T *)handler->getRawPixelsRW(r, &stride); | |||||
if (directDecode) buf = (PIXEL_T *)handler->getRawBufferRW(r, &stride); | |||||
else buf = (PIXEL_T *)reader->getImageBuf(r.area()); | else buf = (PIXEL_T *)reader->getImageBuf(r.area()); | ||||
if (palSize == 0) { | if (palSize == 0) { | ||||
} | } | ||||
} | } | ||||
if (directDecode) handler->releaseRawPixels(r); | |||||
if (directDecode) handler->releaseRawBuffer(r); | |||||
else IMAGE_RECT(r, buf); | else IMAGE_RECT(r, buf); | ||||
delete [] netbuf; | delete [] netbuf; | ||||
// We always use direct decoding with JPEG images | // We always use direct decoding with JPEG images | ||||
int stride; | int stride; | ||||
rdr::U8 *buf = handler->getRawPixelsRW(r, &stride); | |||||
rdr::U8 *buf = handler->getRawBufferRW(r, &stride); | |||||
jd.decompress(netbuf, compressedLen, buf, stride * clientpf.bpp / 8, r, | jd.decompress(netbuf, compressedLen, buf, stride * clientpf.bpp / 8, r, | ||||
clientpf); | clientpf); | ||||
handler->releaseRawPixels(r); | |||||
handler->releaseRawBuffer(r); | |||||
delete [] netbuf; | delete [] netbuf; | ||||
} | } |
{ | { | ||||
int stride; | int stride; | ||||
rdr::U32 solidColor; | rdr::U32 solidColor; | ||||
const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawPixelsR(r, &stride); | |||||
const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawBufferR(r, &stride); | |||||
PIXEL_T *pixels = NULL; | PIXEL_T *pixels = NULL; | ||||
bool grayScaleJPEG = (jpegSubsampling == SUBSAMP_GRAY && jpegQuality != -1); | bool grayScaleJPEG = (jpegSubsampling == SUBSAMP_GRAY && jpegQuality != -1); | ||||
int w = r.width(), h = r.height(); | int w = r.width(), h = r.height(); | ||||
int stride = w; | int stride = w; | ||||
buf = (const PIXEL_T *)ig->getRawPixelsR(r, &stride); | |||||
buf = (const PIXEL_T *)ig->getRawBufferR(r, &stride); | |||||
colorValue = *buf; | colorValue = *buf; | ||||
if (needSameColor && (rdr::U32)colorValue != *colorPtr) | if (needSameColor && (rdr::U32)colorValue != *colorPtr) |
} | } | ||||
} | } | ||||
rdr::U8* CConn::getRawPixelsRW(const rfb::Rect& r, int* stride) { | |||||
return desktop->getPixelsRW(r, stride); | |||||
rdr::U8* CConn::getRawBufferRW(const rfb::Rect& r, int* stride) { | |||||
return desktop->getBufferRW(r, stride); | |||||
} | } | ||||
void CConn::releaseRawPixels(const rfb::Rect& r) { | |||||
void CConn::releaseRawBuffer(const rfb::Rect& r) { | |||||
desktop->damageRect(r); | desktop->damageRect(r); | ||||
} | } | ||||
void imageRect(const rfb::Rect& r, void* p); | void imageRect(const rfb::Rect& r, void* p); | ||||
void copyRect(const rfb::Rect& r, int sx, int sy); | void copyRect(const rfb::Rect& r, int sx, int sy); | ||||
rdr::U8* getRawPixelsRW(const rfb::Rect& r, int* stride); | |||||
void releaseRawPixels(const rfb::Rect& r); | |||||
rdr::U8* getRawBufferRW(const rfb::Rect& r, int* stride); | |||||
void releaseRawBuffer(const rfb::Rect& r); | |||||
const rfb::PixelFormat &getPreferredPF() { return fullColourPF; } | const rfb::PixelFormat &getPreferredPF() { return fullColourPF; } | ||||
viewport->copyRect(r, srcX, srcY); | viewport->copyRect(r, srcX, srcY); | ||||
} | } | ||||
rdr::U8* getPixelsRW(const rfb::Rect& r, int* stride) { | |||||
return viewport->getPixelsRW(r, stride); | |||||
rdr::U8* getBufferRW(const rfb::Rect& r, int* stride) { | |||||
return viewport->getBufferRW(r, stride); | |||||
} | } | ||||
void damageRect(const rfb::Rect& r) { | void damageRect(const rfb::Rect& r) { | ||||
viewport->damageRect(r); | viewport->damageRect(r); |
damageRect(r); | damageRect(r); | ||||
} | } | ||||
rdr::U8* getPixelsRW(const rfb::Rect& r, int* stride) { | |||||
return frameBuffer->getPixelsRW(r, stride); | |||||
rdr::U8* getBufferRW(const rfb::Rect& r, int* stride) { | |||||
return frameBuffer->getBufferRW(r, stride); | |||||
} | } | ||||
void damageRect(const rfb::Rect& r) { | void damageRect(const rfb::Rect& r) { |