Commit 632391db authored by Alexandre Julliard's avatar Alexandre Julliard

wineps: Add a couple of helper functions to simplify the StretchDIBits implementation.

parent 116160f4
......@@ -94,44 +94,16 @@ static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, const BITMAPINFO *info, INT xDst
INT yDst, INT widthDst, INT heightDst,
INT widthSrc, INT heightSrc)
{
COLORREF map[256];
int i;
switch(info->bmiHeader.biBitCount) {
case 8:
PSDRV_WriteIndexColorSpaceBegin(dev, 255);
for(i = 0; i < 256; i++) {
map[i] = info->bmiColors[i].rgbRed |
info->bmiColors[i].rgbGreen << 8 |
info->bmiColors[i].rgbBlue << 16;
}
PSDRV_WriteRGB(dev, map, 256);
PSDRV_WriteIndexColorSpaceEnd(dev);
break;
case 4:
PSDRV_WriteIndexColorSpaceBegin(dev, 15);
for(i = 0; i < 16; i++) {
map[i] = info->bmiColors[i].rgbRed |
info->bmiColors[i].rgbGreen << 8 |
info->bmiColors[i].rgbBlue << 16;
}
PSDRV_WriteRGB(dev, map, 16);
PSDRV_WriteIndexColorSpaceEnd(dev);
break;
switch(info->bmiHeader.biBitCount)
{
case 1:
PSDRV_WriteIndexColorSpaceBegin(dev, 1);
for(i = 0; i < 2; i++) {
map[i] = info->bmiColors[i].rgbRed |
info->bmiColors[i].rgbGreen << 8 |
info->bmiColors[i].rgbBlue << 16;
}
PSDRV_WriteRGB(dev, map, 2);
case 4:
case 8:
PSDRV_WriteIndexColorSpaceBegin(dev, (1 << info->bmiHeader.biBitCount) - 1);
PSDRV_WriteRGBQUAD(dev, info->bmiColors, 1 << info->bmiHeader.biBitCount);
PSDRV_WriteIndexColorSpaceEnd(dev);
break;
case 15:
case 16:
case 24:
case 32:
......@@ -142,14 +114,10 @@ static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, const BITMAPINFO *info, INT xDst
PSDRV_WriteSetColor(dev, &pscol);
break;
}
default:
FIXME("Not implemented yet\n");
return FALSE;
}
PSDRV_WriteImage(dev, info->bmiHeader.biBitCount, xDst, yDst,
widthDst, heightDst, widthSrc, heightSrc, FALSE);
widthDst, heightDst, widthSrc, heightSrc, FALSE, info->bmiHeader.biHeight < 0);
return TRUE;
}
......@@ -170,24 +138,20 @@ static BOOL PSDRV_WriteImageMaskHeader(PHYSDEV dev, const BITMAPINFO *info, INT
INT yDst, INT widthDst, INT heightDst,
INT widthSrc, INT heightSrc)
{
COLORREF map[2];
PSCOLOR bkgnd, foregnd;
int i;
assert(info->bmiHeader.biBitCount == 1);
for(i = 0; i < 2; i++) {
map[i] = info->bmiColors[i].rgbRed |
info->bmiColors[i].rgbGreen << 8 |
info->bmiColors[i].rgbBlue << 16;
}
/* We'll write the mask with -ve polarity so that
the foregnd color corresponds to a bit equal to
0 in the bitmap.
*/
PSDRV_CreateColor(dev, &foregnd, map[0]);
PSDRV_CreateColor(dev, &bkgnd, map[1]);
PSDRV_CreateColor(dev, &foregnd, RGB(info->bmiColors[0].rgbRed,
info->bmiColors[0].rgbGreen,
info->bmiColors[0].rgbBlue) );
PSDRV_CreateColor(dev, &bkgnd, RGB(info->bmiColors[1].rgbRed,
info->bmiColors[1].rgbGreen,
info->bmiColors[1].rgbBlue) );
PSDRV_WriteGSave(dev);
PSDRV_WriteNewPath(dev);
......@@ -198,7 +162,7 @@ static BOOL PSDRV_WriteImageMaskHeader(PHYSDEV dev, const BITMAPINFO *info, INT
PSDRV_WriteSetColor(dev, &foregnd);
PSDRV_WriteImage(dev, 1, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc, TRUE);
widthSrc, heightSrc, TRUE, info->bmiHeader.biHeight < 0);
return TRUE;
}
......@@ -214,6 +178,34 @@ static inline DWORD max_ascii85_size(DWORD size)
}
/***************************************************************************
* PSDRV_WriteImageBits
*/
static void PSDRV_WriteImageBits( PHYSDEV dev, const BITMAPINFO *info, INT xDst, INT yDst,
INT widthDst, INT heightDst, INT widthSrc, INT heightSrc,
void *bits, DWORD size )
{
BYTE *rle, *ascii85;
DWORD rle_len, ascii85_len;
if (info->bmiHeader.biBitCount == 1)
/* Use imagemask rather than image */
PSDRV_WriteImageMaskHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
else
PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
rle = HeapAlloc(GetProcessHeap(), 0, max_rle_size(size));
rle_len = RLE_encode(bits, size, rle);
ascii85 = HeapAlloc(GetProcessHeap(), 0, max_ascii85_size(rle_len));
ascii85_len = ASCII85_encode(rle, rle_len, ascii85);
HeapFree(GetProcessHeap(), 0, rle);
PSDRV_WriteData(dev, ascii85, ascii85_len);
PSDRV_WriteSpool(dev, "~>\n", 3);
HeapFree(GetProcessHeap(), 0, ascii85);
}
/***************************************************************************
*
* PSDRV_StretchDIBits
*
......@@ -232,8 +224,8 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT line;
POINT pt[2];
const BYTE *src_ptr;
BYTE *dst_ptr, *bitmap, *rle, *ascii85;
DWORD rle_len, ascii85_len, bitmap_size;
BYTE *dst_ptr, *bitmap;
DWORD bitmap_size;
TRACE("%p (%d,%d %dx%d) -> (%d,%d %dx%d)\n", dev->hdc,
xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst);
......@@ -241,7 +233,6 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
if (!get_bitmap_info( info, &fullSrcWidth, &fullSrcHeight, &bpp, &compression )) return FALSE;
stride = get_dib_width_bytes(fullSrcWidth, bpp);
if(fullSrcHeight < 0) stride = -stride; /* top-down */
TRACE("full size=%dx%d bpp=%d compression=%d rop=%08x\n", fullSrcWidth,
fullSrcHeight, bpp, compression, dwRop);
......@@ -265,14 +256,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
switch(bpp) {
case 1:
PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev);
/* Use imagemask rather than image */
PSDRV_WriteImageMaskHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
src_ptr = bits;
if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride;
src_ptr += (ySrc * stride);
if(xSrc & 7)
FIXME("This won't work...\n");
......@@ -283,12 +267,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
break;
case 4:
PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev);
PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
src_ptr = bits;
if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride;
src_ptr += (ySrc * stride);
if(xSrc & 1)
FIXME("This won't work...\n");
......@@ -299,12 +278,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
break;
case 8:
PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev);
PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
src_ptr = bits;
if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride;
src_ptr += (ySrc * stride);
bitmap_size = heightSrc * widthSrc;
dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size);
......@@ -312,16 +286,8 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
memcpy(dst_ptr, src_ptr + xSrc, widthSrc);
break;
case 15:
case 16:
PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev);
PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
src_ptr = bits;
if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride;
src_ptr += (ySrc * stride);
bitmap_size = heightSrc * widthSrc * 3;
dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size);
......@@ -348,13 +314,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
break;
case 24:
PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev);
PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
src_ptr = bits;
if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride;
src_ptr += (ySrc * stride);
bitmap_size = heightSrc * widthSrc * 3;
dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size);
......@@ -371,13 +331,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
break;
case 32:
PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev);
PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc);
src_ptr = bits;
if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride;
src_ptr += (ySrc * stride);
bitmap_size = heightSrc * widthSrc * 3;
dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size);
......@@ -399,15 +353,11 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
}
rle = HeapAlloc(GetProcessHeap(), 0, max_rle_size(bitmap_size));
rle_len = RLE_encode(bitmap, bitmap_size, rle);
PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev);
PSDRV_WriteImageBits( dev, info, xDst, yDst, widthDst, heightDst,
widthSrc, heightSrc, bitmap, bitmap_size );
HeapFree(GetProcessHeap(), 0, bitmap);
ascii85 = HeapAlloc(GetProcessHeap(), 0, max_ascii85_size(rle_len));
ascii85_len = ASCII85_encode(rle, rle_len, ascii85);
HeapFree(GetProcessHeap(), 0, rle);
PSDRV_WriteData(dev, ascii85, ascii85_len);
HeapFree(GetProcessHeap(), 0, ascii85);
PSDRV_WriteSpool(dev, "~>\n", 3);
PSDRV_WriteGRestore(dev);
PSDRV_ResetClip(dev);
return abs(heightSrc);
......
......@@ -672,8 +672,23 @@ BOOL PSDRV_WriteRGB(PHYSDEV dev, COLORREF *map, int number)
return TRUE;
}
BOOL PSDRV_WriteRGBQUAD(PHYSDEV dev, const RGBQUAD *rgb, int number)
{
char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1), *ptr;
int i;
ptr = buf;
for(i = 0; i < number; i++)
ptr += sprintf(ptr, "%02x%02x%02x%c", rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue,
((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' ');
PSDRV_WriteSpool(dev, buf, ptr - buf);
HeapFree(PSDRV_Heap, 0, buf);
return TRUE;
}
static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth,
INT widthSrc, INT heightSrc, char *bits)
INT widthSrc, INT heightSrc, char *bits, BOOL top_down)
{
static const char start[] = "<<\n"
" /ImageType 1\n /Width %d\n /Height %d\n /BitsPerComponent %d\n"
......@@ -687,8 +702,12 @@ static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth,
char *buf = HeapAlloc(PSDRV_Heap, 0, 1000);
sprintf(buf, start, widthSrc, heightSrc,
(depth < 8) ? depth : 8, widthSrc, -heightSrc, heightSrc);
if (top_down)
sprintf(buf, start, widthSrc, heightSrc,
(depth < 8) ? depth : 8, widthSrc, heightSrc, 0);
else
sprintf(buf, start, widthSrc, heightSrc,
(depth < 8) ? depth : 8, widthSrc, -heightSrc, heightSrc);
PSDRV_WriteSpool(dev, buf, strlen(buf));
......@@ -725,7 +744,7 @@ static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth,
BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst,
INT widthDst, INT heightDst, INT widthSrc,
INT heightSrc, BOOL mask)
INT heightSrc, BOOL mask, BOOL top_down)
{
static const char start[] = "%d %d translate\n%d %d scale\n";
static const char image[] = "image\n";
......@@ -734,7 +753,7 @@ BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst,
sprintf(buf, start, xDst, yDst, widthDst, heightDst);
PSDRV_WriteSpool(dev, buf, strlen(buf));
PSDRV_WriteImageDict(dev, depth, widthSrc, heightSrc, NULL);
PSDRV_WriteImageDict(dev, depth, widthSrc, heightSrc, NULL, top_down);
if(mask)
PSDRV_WriteSpool(dev, imagemask, sizeof(imagemask) - 1);
else
......@@ -835,7 +854,7 @@ BOOL PSDRV_WritePatternDict(PHYSDEV dev, BITMAP *bm, BYTE *bits)
}
}
PSDRV_WriteSpool(dev, mypat, sizeof(mypat) - 1);
PSDRV_WriteImageDict(dev, 1, 8, 8, buf);
PSDRV_WriteImageDict(dev, 1, 8, 8, buf, FALSE);
PSDRV_WriteSpool(dev, "def\n", 4);
PSDRV_WriteIndexColorSpaceBegin(dev, 1);
......@@ -892,7 +911,7 @@ BOOL PSDRV_WriteDIBPatternDict(PHYSDEV dev, BITMAPINFO *bmi, UINT usage)
}
}
PSDRV_WriteSpool(dev, mypat, sizeof(mypat) - 1);
PSDRV_WriteImageDict(dev, 1, 8, 8, buf);
PSDRV_WriteImageDict(dev, 1, 8, 8, buf, FALSE);
PSDRV_WriteSpool(dev, "def\n", 4);
PSDRV_WriteIndexColorSpaceBegin(dev, 1);
......
......@@ -516,9 +516,10 @@ extern BOOL PSDRV_WriteRotate(PHYSDEV dev, float ang) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteIndexColorSpaceBegin(PHYSDEV dev, int size) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteIndexColorSpaceEnd(PHYSDEV dev) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteRGB(PHYSDEV dev, COLORREF *map, int number) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteRGBQUAD(PHYSDEV dev, const RGBQUAD *rgb, int number) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst,
INT widthDst, INT heightDst, INT widthSrc,
INT heightSrc, BOOL mask) DECLSPEC_HIDDEN;
INT heightSrc, BOOL mask, BOOL top_down) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteBytes(PHYSDEV dev, const BYTE *bytes, DWORD number) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteData(PHYSDEV dev, const BYTE *byte, DWORD number) DECLSPEC_HIDDEN;
extern DWORD PSDRV_WriteSpool(PHYSDEV dev, LPCSTR lpData, DWORD cch) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment