/*
 *	PostScript driver bitmap functions
 *
 * Copyright 1998  Huw D M Davies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <assert.h>
#include <stdlib.h>

#include "psdrv.h"
#include "winbase.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(psdrv);


/* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned. */
static inline int get_dib_width_bytes( int width, int depth )
{
    return ((width * depth + 31) / 8) & ~3;
}


/***************************************************************************
 *                PSDRV_WriteImageHeader
 *
 * Helper for PSDRV_PutImage
 *
 * BUGS
 *  Uses level 2 PostScript
 */

static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, const BITMAPINFO *info, BOOL grayscale, INT xDst,
				   INT yDst, INT widthDst, INT heightDst,
				   INT widthSrc, INT heightSrc)
{
    switch(info->bmiHeader.biBitCount)
    {
    case 1:
    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 16:
    case 24:
    case 32:
      {
	PSCOLOR pscol;
        if (grayscale)
        {
            pscol.type = PSCOLOR_GRAY;
            pscol.value.gray.i = 0;
        }
        else
        {
            pscol.type = PSCOLOR_RGB;
            pscol.value.rgb.r = pscol.value.rgb.g = pscol.value.rgb.b = 0.0;
        }
        PSDRV_WriteSetColor(dev, &pscol);
        break;
      }
    }

    PSDRV_WriteImage(dev, info->bmiHeader.biBitCount, grayscale, xDst, yDst,
		     widthDst, heightDst, widthSrc, heightSrc, FALSE, info->bmiHeader.biHeight < 0);
    return TRUE;
}


/***************************************************************************
 *                PSDRV_WriteImageMaskHeader
 *
 * Helper for PSDRV_PutImage
 *
 * We use the imagemask operator for 1bpp bitmaps since the output
 * takes much less time for the printer to render.
 *
 * BUGS
 *  Uses level 2 PostScript
 */

static BOOL PSDRV_WriteImageMaskHeader(PHYSDEV dev, const BITMAPINFO *info, INT xDst,
                                       INT yDst, INT widthDst, INT heightDst,
                                       INT widthSrc, INT heightSrc)
{
    PSCOLOR bkgnd, foregnd;

    assert(info->bmiHeader.biBitCount == 1);

    /* 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, 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);
    PSDRV_WriteRectangle(dev, xDst, yDst, widthDst, heightDst);
    PSDRV_WriteSetColor(dev, &bkgnd);
    PSDRV_WriteFill(dev);
    PSDRV_WriteGRestore(dev);

    PSDRV_WriteSetColor(dev, &foregnd);
    PSDRV_WriteImage(dev, 1, FALSE, xDst, yDst, widthDst, heightDst,
		     widthSrc, heightSrc, TRUE, info->bmiHeader.biHeight < 0);

    return TRUE;
}

static inline DWORD max_rle_size(DWORD size)
{
    return size + (size + 127) / 128 + 1;
}

static inline DWORD max_ascii85_size(DWORD size)
{
    return (size + 3) / 4 * 5;
}

static void free_heap_bits( struct gdi_image_bits *bits )
{
    HeapFree( GetProcessHeap(), 0, bits->ptr );
}

/***************************************************************************
 *                PSDRV_WriteImageBits
 */
static void PSDRV_WriteImageBits( PHYSDEV dev, const BITMAPINFO *info, BOOL grayscale, 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, grayscale, 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_PutImage
 */
DWORD PSDRV_PutImage( PHYSDEV dev, HRGN clip, BITMAPINFO *info,
                      const struct gdi_image_bits *bits, struct bitblt_coords *src,
                      struct bitblt_coords *dst, DWORD rop )
{
    int src_stride, dst_stride, size, x, y, width, height, bit_offset;
    int dst_x, dst_y, dst_width, dst_height;
    unsigned char *src_ptr, *dst_ptr;
    struct gdi_image_bits dst_bits;
    PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
    BOOL grayscale = info->bmiHeader.biBitCount == 24 && physDev->pi->ppd->ColorDevice == CD_False;

    if (info->bmiHeader.biPlanes != 1) goto update_format;
    if (info->bmiHeader.biCompression != BI_RGB) goto update_format;
    if (info->bmiHeader.biBitCount == 16 || info->bmiHeader.biBitCount == 32) goto update_format;
    if (!bits) return ERROR_SUCCESS;  /* just querying the format */

    TRACE( "bpp %u %s -> %s\n", info->bmiHeader.biBitCount, wine_dbgstr_rect(&src->visrect),
           wine_dbgstr_rect(&dst->visrect) );

    width = src->visrect.right - src->visrect.left;
    height = src->visrect.bottom - src->visrect.top;
    src_stride = get_dib_width_bytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
    if (grayscale) dst_stride = width;
    else dst_stride = (width * info->bmiHeader.biBitCount + 7) / 8;

    src_ptr = bits->ptr;
    if (info->bmiHeader.biHeight > 0)
        src_ptr += (info->bmiHeader.biHeight - src->visrect.bottom) * src_stride;
    else
        src_ptr += src->visrect.top * src_stride;
    bit_offset = src->visrect.left * info->bmiHeader.biBitCount;
    src_ptr += bit_offset / 8;
    bit_offset &= 7;
    if (bit_offset) FIXME( "pos %s not supported\n", wine_dbgstr_rect(&src->visrect) );
    size = height * dst_stride;

    if (src_stride != dst_stride || (info->bmiHeader.biBitCount == 24 && !bits->is_copy))
    {
        if (!(dst_bits.ptr = HeapAlloc( GetProcessHeap(), 0, size ))) return ERROR_OUTOFMEMORY;
        dst_bits.is_copy = TRUE;
        dst_bits.free = free_heap_bits;
    }
    else
    {
        dst_bits.ptr = src_ptr;
        dst_bits.is_copy = bits->is_copy;
        dst_bits.free = NULL;
    }
    dst_ptr = dst_bits.ptr;

    switch (info->bmiHeader.biBitCount)
    {
    case 1:
    case 4:
    case 8:
        if (src_stride != dst_stride)
            for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride)
                memcpy( dst_ptr, src_ptr, dst_stride );
        break;
    case 24:
        if (grayscale)
        {
            PSRGB scale = rgb_to_grayscale_scale();
            for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride)
                for (x = 0; x < width; x++)
                    dst_ptr[x] = src_ptr[x * 3 + 2] * scale.r + src_ptr[x * 3 + 1] * scale.g + src_ptr[x * 3] * scale.b;
        }
        else if (dst_ptr != src_ptr)
            for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride)
                for (x = 0; x < width; x++)
                {
                    dst_ptr[x * 3]     = src_ptr[x * 3 + 2];
                    dst_ptr[x * 3 + 1] = src_ptr[x * 3 + 1];
                    dst_ptr[x * 3 + 2] = src_ptr[x * 3];
                }
        else  /* swap R and B in place */
            for (y = 0; y < height; y++, src_ptr += src_stride, dst_ptr += dst_stride)
                for (x = 0; x < width; x++)
                {
                    unsigned char tmp = dst_ptr[x * 3];
                    dst_ptr[x * 3] = dst_ptr[x * 3 + 2];
                    dst_ptr[x * 3 + 2] = tmp;
                }
        break;
    }

    dst_x = dst->visrect.left;
    dst_y = dst->visrect.top,
    dst_width = dst->visrect.right - dst->visrect.left;
    dst_height = dst->visrect.bottom - dst->visrect.top;
    if (src->width * dst->width < 0)
    {
        dst_x += dst_width;
        dst_width = -dst_width;
    }
    if (src->height * dst->height < 0)
    {
        dst_y += dst_height;
        dst_height = -dst_height;
    }

    PSDRV_SetClip(dev);
    PSDRV_WriteGSave(dev);
    if (clip) PSDRV_AddClip( dev, clip );
    PSDRV_WriteImageBits( dev, info, grayscale, dst_x, dst_y, dst_width, dst_height,
                          width, height, dst_bits.ptr, size );
    PSDRV_WriteGRestore(dev);
    PSDRV_ResetClip(dev);
    if (dst_bits.free) dst_bits.free( &dst_bits );
    return ERROR_SUCCESS;

update_format:
    info->bmiHeader.biPlanes = 1;
    if (info->bmiHeader.biBitCount > 8) info->bmiHeader.biBitCount = 24;
    info->bmiHeader.biCompression = BI_RGB;
    return ERROR_BAD_FORMAT;
}
