зеркало из https://github.com/mozilla/pjs.git
Bug 723221 - Premultiply JPG data correctly - r=joe
This commit is contained in:
Родитель
0cba88efa3
Коммит
111d23ae54
|
@ -41,6 +41,7 @@
|
||||||
#include "prprf.h"
|
#include "prprf.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStreamUtils.h"
|
#include "nsStreamUtils.h"
|
||||||
|
#include "gfxColor.h"
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include "jerror.h"
|
#include "jerror.h"
|
||||||
|
@ -186,7 +187,7 @@ NS_IMETHODIMP nsJPEGEncoder::InitFromData(const PRUint8* aData,
|
||||||
} else if (aInputFormat == INPUT_FORMAT_RGBA) {
|
} else if (aInputFormat == INPUT_FORMAT_RGBA) {
|
||||||
PRUint8* row = new PRUint8[aWidth * 3];
|
PRUint8* row = new PRUint8[aWidth * 3];
|
||||||
while (cinfo.next_scanline < cinfo.image_height) {
|
while (cinfo.next_scanline < cinfo.image_height) {
|
||||||
StripAlpha(&aData[cinfo.next_scanline * aStride], row, aWidth);
|
ConvertRGBARow(&aData[cinfo.next_scanline * aStride], row, aWidth);
|
||||||
jpeg_write_scanlines(&cinfo, &row, 1);
|
jpeg_write_scanlines(&cinfo, &row, 1);
|
||||||
}
|
}
|
||||||
delete[] row;
|
delete[] row;
|
||||||
|
@ -350,46 +351,48 @@ NS_IMETHODIMP nsJPEGEncoder::CloseWithStatus(nsresult aStatus)
|
||||||
return Close();
|
return Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// nsJPEGEncoder::ConvertHostARGBRow
|
// nsJPEGEncoder::ConvertHostARGBRow
|
||||||
//
|
//
|
||||||
// Our colors are stored with premultiplied alphas, but we need
|
// Our colors are stored with premultiplied alphas, but we need
|
||||||
// an output with no alpha in machine-independent byte order.
|
// an output with no alpha in machine-independent byte order.
|
||||||
//
|
//
|
||||||
// See gfx/cairo/cairo/src/cairo-png.c
|
// See gfx/cairo/cairo/src/cairo-png.c
|
||||||
|
|
||||||
void
|
void
|
||||||
nsJPEGEncoder::ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest,
|
nsJPEGEncoder::ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest,
|
||||||
PRUint32 aPixelWidth)
|
PRUint32 aPixelWidth)
|
||||||
{
|
{
|
||||||
for (PRUint32 x = 0; x < aPixelWidth; x ++) {
|
for (PRUint32 x = 0; x < aPixelWidth; x++) {
|
||||||
const PRUint32& pixelIn = ((const PRUint32*)(aSrc))[x];
|
const PRUint32& pixelIn = ((const PRUint32*)(aSrc))[x];
|
||||||
PRUint8 *pixelOut = &aDest[x * 3];
|
PRUint8 *pixelOut = &aDest[x * 3];
|
||||||
|
|
||||||
pixelOut[0] = (((pixelIn & 0xff0000) >> 16));
|
pixelOut[0] = (pixelIn & 0xff0000) >> 16;
|
||||||
pixelOut[1] = (((pixelIn & 0x00ff00) >> 8));
|
pixelOut[1] = (pixelIn & 0x00ff00) >> 8;
|
||||||
pixelOut[2] = (((pixelIn & 0x0000ff) >> 0));
|
pixelOut[2] = (pixelIn & 0x0000ff) >> 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
// nsJPEGEncoder::StripAlpha
|
* nsJPEGEncoder::ConvertRGBARow
|
||||||
//
|
*
|
||||||
// Input is RGBA, output is RGB
|
* Input is RGBA, output is RGB, so we should alpha-premultiply.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
nsJPEGEncoder::StripAlpha(const PRUint8* aSrc, PRUint8* aDest,
|
nsJPEGEncoder::ConvertRGBARow(const PRUint8* aSrc, PRUint8* aDest,
|
||||||
PRUint32 aPixelWidth)
|
PRUint32 aPixelWidth)
|
||||||
{
|
{
|
||||||
for (PRUint32 x = 0; x < aPixelWidth; x ++) {
|
for (PRUint32 x = 0; x < aPixelWidth; x++) {
|
||||||
const PRUint8* pixelIn = &aSrc[x * 4];
|
const PRUint8* pixelIn = &aSrc[x * 4];
|
||||||
PRUint8* pixelOut = &aDest[x * 3];
|
PRUint8* pixelOut = &aDest[x * 3];
|
||||||
pixelOut[0] = pixelIn[0];
|
|
||||||
pixelOut[1] = pixelIn[1];
|
PRUint8 alpha = pixelIn[3];
|
||||||
pixelOut[2] = pixelIn[2];
|
pixelOut[0] = GFX_PREMULTIPLY(pixelIn[0], alpha);
|
||||||
|
pixelOut[1] = GFX_PREMULTIPLY(pixelIn[1], alpha);
|
||||||
|
pixelOut[2] = GFX_PREMULTIPLY(pixelIn[2], alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// nsJPEGEncoder::initDestination
|
// nsJPEGEncoder::initDestination
|
||||||
//
|
//
|
||||||
// Initialize destination. This is called by jpeg_start_compress() before
|
// Initialize destination. This is called by jpeg_start_compress() before
|
||||||
|
|
|
@ -78,7 +78,7 @@ protected:
|
||||||
|
|
||||||
void ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest,
|
void ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest,
|
||||||
PRUint32 aPixelWidth);
|
PRUint32 aPixelWidth);
|
||||||
void StripAlpha(const PRUint8* aSrc, PRUint8* aDest, PRUint32 aPixelWidth);
|
void ConvertRGBARow(const PRUint8* aSrc, PRUint8* aDest, PRUint32 aPixelWidth);
|
||||||
|
|
||||||
static void initDestination(jpeg_compress_struct* cinfo);
|
static void initDestination(jpeg_compress_struct* cinfo);
|
||||||
static boolean emptyOutputBuffer(jpeg_compress_struct* cinfo);
|
static boolean emptyOutputBuffer(jpeg_compress_struct* cinfo);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче