Consistently use the term stride rather than pitch. Also consistently represent the stride in number of pixels rather than number of bytes. There is so much code that assumes proper alignment already that we do not need the extra resolution.tags/v1.3.90
delete cinfo; | delete cinfo; | ||||
} | } | ||||
void JpegCompressor::compress(const rdr::U8 *buf, int pitch, const Rect& r, | |||||
void JpegCompressor::compress(const rdr::U8 *buf, int stride, const Rect& r, | |||||
const PixelFormat& pf, int quality, int subsamp) | const PixelFormat& pf, int quality, int subsamp) | ||||
{ | { | ||||
int w = r.width(); | int w = r.width(); | ||||
} | } | ||||
#endif | #endif | ||||
if (pitch == 0) pitch = w * pf.bpp / 8; | |||||
if (stride == 0) | |||||
stride = w; | |||||
if (cinfo->in_color_space == JCS_RGB) { | if (cinfo->in_color_space == JCS_RGB) { | ||||
srcBuf = new rdr::U8[w * h * pixelsize]; | srcBuf = new rdr::U8[w * h * pixelsize]; | ||||
srcBufIsTemp = true; | srcBufIsTemp = true; | ||||
pf.rgbFromBuffer(srcBuf, (const rdr::U8 *)buf, w, pitch, h); | |||||
pitch = w * pixelsize; | |||||
pf.rgbFromBuffer(srcBuf, (const rdr::U8 *)buf, w, stride, h); | |||||
stride = w; | |||||
} | } | ||||
cinfo->input_components = pixelsize; | cinfo->input_components = pixelsize; | ||||
rowPointer = new JSAMPROW[h]; | rowPointer = new JSAMPROW[h]; | ||||
for (int dy = 0; dy < h; dy++) | for (int dy = 0; dy < h; dy++) | ||||
rowPointer[dy] = (JSAMPROW)(&srcBuf[dy * pitch]); | |||||
rowPointer[dy] = (JSAMPROW)(&srcBuf[dy * stride * pixelsize]); | |||||
jpeg_start_compress(cinfo, TRUE); | jpeg_start_compress(cinfo, TRUE); | ||||
while (cinfo->next_scanline < cinfo->image_height) | while (cinfo->next_scanline < cinfo->image_height) |
} | } | ||||
void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen, | void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen, | ||||
rdr::U8 *buf, int pitch, const Rect& r, const PixelFormat& pf) | |||||
rdr::U8 *buf, int stride, const Rect& r, const PixelFormat& pf) | |||||
{ | { | ||||
int w = r.width(); | int w = r.width(); | ||||
int h = r.height(); | int h = r.height(); | ||||
int pixelsize; | int pixelsize; | ||||
int dstBufPitch; | |||||
int dstBufStride; | |||||
rdr::U8 *dstBuf = NULL; | rdr::U8 *dstBuf = NULL; | ||||
bool dstBufIsTemp = false; | bool dstBufIsTemp = false; | ||||
JSAMPROW *rowPointer = NULL; | JSAMPROW *rowPointer = NULL; | ||||
jpeg_read_header(dinfo, TRUE); | jpeg_read_header(dinfo, TRUE); | ||||
dinfo->out_color_space = JCS_RGB; | dinfo->out_color_space = JCS_RGB; | ||||
pixelsize = 3; | pixelsize = 3; | ||||
if (pitch == 0) pitch = w * pf.bpp / 8; | |||||
dstBufPitch = pitch; | |||||
if (stride == 0) | |||||
stride = w; | |||||
dstBufStride = stride; | |||||
#ifdef JCS_EXTENSIONS | #ifdef JCS_EXTENSIONS | ||||
// Try to have libjpeg output directly to our native format | // Try to have libjpeg output directly to our native format | ||||
if (dinfo->out_color_space == JCS_RGB) { | if (dinfo->out_color_space == JCS_RGB) { | ||||
dstBuf = new rdr::U8[w * h * pixelsize]; | dstBuf = new rdr::U8[w * h * pixelsize]; | ||||
dstBufIsTemp = true; | dstBufIsTemp = true; | ||||
dstBufPitch = w * pixelsize; | |||||
dstBufStride = w; | |||||
} | } | ||||
rowPointer = new JSAMPROW[h]; | rowPointer = new JSAMPROW[h]; | ||||
for (int dy = 0; dy < h; dy++) | for (int dy = 0; dy < h; dy++) | ||||
rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufPitch]); | |||||
rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufStride * pixelsize]); | |||||
jpeg_start_decompress(dinfo); | jpeg_start_decompress(dinfo); | ||||
} | } | ||||
if (dinfo->out_color_space == JCS_RGB) | if (dinfo->out_color_space == JCS_RGB) | ||||
pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, pitch, h); | |||||
pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, stride, h); | |||||
jpeg_finish_decompress(dinfo); | jpeg_finish_decompress(dinfo); | ||||
} | } | ||||
void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, | void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, | ||||
int w, int pitch, int h, ColourMap* cm) const | |||||
int w, int stride, int h, ColourMap* cm) const | |||||
{ | { | ||||
if (is888()) { | if (is888()) { | ||||
// Optimised common case | // Optimised common case | ||||
x = dst + (48 - redShift - greenShift - blueShift)/8; | x = dst + (48 - redShift - greenShift - blueShift)/8; | ||||
} | } | ||||
int dstPad = pitch - w * 4; | |||||
int dstPad = (stride - w) * 4; | |||||
while (h--) { | while (h--) { | ||||
int w_ = w; | int w_ = w; | ||||
while (w_--) { | while (w_--) { | ||||
} | } | ||||
} else { | } else { | ||||
// Generic code | // Generic code | ||||
int dstPad = pitch - w * 4; | |||||
int dstPad = (stride - w) * 4; | |||||
while (h--) { | while (h--) { | ||||
int w_ = w; | int w_ = w; | ||||
while (w_--) { | while (w_--) { | ||||
void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, | void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, | ||||
int w, int pitch, int h, ColourMap* cm) const | |||||
int w, int stride, int h, ColourMap* cm) const | |||||
{ | { | ||||
if (is888()) { | if (is888()) { | ||||
// Optimised common case | // Optimised common case | ||||
b = src + blueShift/8; | b = src + blueShift/8; | ||||
} | } | ||||
int srcPad = pitch - w * 4; | |||||
int srcPad = (stride - w) * 4; | |||||
while (h--) { | while (h--) { | ||||
int w_ = w; | int w_ = w; | ||||
while (w_--) { | while (w_--) { | ||||
} | } | ||||
} else { | } else { | ||||
// Generic code | // Generic code | ||||
int srcPad = pitch - w * bpp/8; | |||||
int srcPad = (stride - w) * bpp/8; | |||||
while (h--) { | while (h--) { | ||||
int w_ = w; | int w_ = w; | ||||
while (w_--) { | while (w_--) { |
inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const; | inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const; | ||||
void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; | void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; | ||||
void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int pitch, | |||||
void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int stride, | |||||
int h, ColourMap* cm=0) const; | int h, ColourMap* cm=0) const; | ||||
void rgbFromPixel(Pixel pix, ColourMap* cm, Colour* rgb) const; | void rgbFromPixel(Pixel pix, ColourMap* cm, Colour* rgb) const; | ||||
inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const; | inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const; | ||||
void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; | void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; | ||||
void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int pitch, | |||||
void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int stride, | |||||
int h, ColourMap* cm=0) const; | int h, ColourMap* cm=0) const; | ||||
void print(char* str, int len) const; | void print(char* str, int len) const; |
// We always use direct decoding with JPEG images | // We always use direct decoding with JPEG images | ||||
int stride; | int stride; | ||||
rdr::U8 *buf = handler->getRawBufferRW(r, &stride); | rdr::U8 *buf = handler->getRawBufferRW(r, &stride); | ||||
jd.decompress(netbuf, compressedLen, buf, stride * clientpf.bpp / 8, r, | |||||
clientpf); | |||||
jd.decompress(netbuf, compressedLen, buf, stride, r, clientpf); | |||||
handler->releaseRawBuffer(r); | handler->releaseRawBuffer(r); | ||||
delete [] netbuf; | delete [] netbuf; |
rdr::OutStream *os) | rdr::OutStream *os) | ||||
{ | { | ||||
jc.clear(); | jc.clear(); | ||||
jc.compress((rdr::U8 *)buf, stride * clientpf.bpp / 8, r, clientpf, | |||||
jc.compress((rdr::U8 *)buf, stride, r, clientpf, | |||||
jpegQuality, jpegSubsampling); | jpegQuality, jpegSubsampling); | ||||
os->writeU8(0x09 << 4); | os->writeU8(0x09 << 4); | ||||
os->writeCompactLength(jc.length()); | os->writeCompactLength(jc.length()); |