/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include <glyphcache.hxx>
#include <string.h>

//------------------------------------------------------------------------

RawBitmap::RawBitmap()
: mpBits(0), mnAllocated(0)
{}

//------------------------------------------------------------------------

RawBitmap::~RawBitmap()
{
    delete[] mpBits;
    mpBits = 0;
    mnAllocated = 0;
}

//------------------------------------------------------------------------

// used by 90 and 270 degree rotations on 8 bit deep bitmaps
static void ImplRotate8_90( unsigned char* p1, const unsigned char* p2,
    int xmax, int ymax, int dx, int dy, int nPad )
{
    for( int y = ymax; --y >= 0; p2 += dy )
    {
        for( int x = xmax; --x >= 0; p2 += dx )
            *(p1++) = *p2;
        for( int i = nPad; --i >= 0; )
            *(p1++) = 0;
    }
}

//------------------------------------------------------------------------

// used by inplace 180 degree rotation on 8 bit deep bitmaps
static void ImplRotate8_180( unsigned char* p1, int xmax, int ymax, int nPad )
{
    unsigned char* p2 = p1 + ymax * (xmax + nPad);
    for( int y = ymax/2; --y >= 0; )
    {
        p2 -= nPad;
        for( int x = xmax; --x >= 0; )
        {
            unsigned char cTmp = *(--p2);
            *p2 = *p1;
            *(p1++) = cTmp;
        }
        p1 += nPad;
    }

    // reverse middle line
    p2 -= nPad;
    while( p1 < p2 )
    {
        unsigned char cTmp = *(--p2);
        *p2 = *p1;
        *(p1++) = cTmp;
    }
}

//------------------------------------------------------------------------

// used by 90 or 270 degree rotations on 1 bit deep bitmaps
static void ImplRotate1_90( unsigned char* p1, const unsigned char* p2,
    int xmax, int ymax, int dx, int nShift, int nDeltaShift, int nPad )
{
    for( int y = ymax; --y >= 0; )
    {
        unsigned nTemp = 1;
        const unsigned char* p20 = p2;
        for( int x = xmax; --x >= 0; p2 += dx )
        {
            // build bitwise and store when byte finished
           nTemp += nTemp + ((*p2 >> nShift) & 1);
            if( nTemp >= 0x100U )
            {
                *(p1++) = (unsigned char)nTemp;
                nTemp = 1;
            }
        }
        p2 = p20;

        // store left aligned remainder if needed
        if( nTemp > 1 )
        {
            for(; nTemp < 0x100U; nTemp += nTemp ) ;
            *(p1++) = (unsigned char)nTemp;
        }
        // pad scanline with zeroes
        for( int i = nPad; --i >= 0;)
            *(p1++) = 0;

        // increase/decrease shift, but keep bound inside 0 to 7
        nShift += nDeltaShift;
        if( nShift != (nShift & 7) )
            p2 -= nDeltaShift;
        nShift &= 7;
    }
}

//------------------------------------------------------------------------

// used by 180 degrees rotations on 1 bit deep bitmaps
static void ImplRotate1_180( unsigned char* p1, const unsigned char* p2,
    int xmax, int ymax, int nPad )
{
    --p2;
    for( int y = ymax; --y >= 0; )
    {
        p2 -= nPad;

        unsigned nTemp = 1;
        unsigned nInp = (0x100 + *p2) >> (-xmax & 7);
        for( int x = xmax; --x >= 0; )
        {
            // build bitwise and store when byte finished
            nTemp += nTemp + (nInp & 1);
            if( nTemp >= 0x100 )
            {
                *(p1++) = (unsigned char)nTemp;
                nTemp = 1;
            }
            // update input byte if needed (and available)
            if( (nInp >>= 1) <= 1 && ((y != 0) || (x != 0)) )
                nInp = 0x100 + *(--p2);
        }

        // store left aligned remainder if needed
        if( nTemp > 1 )
        {
            for(; nTemp < 0x100; nTemp += nTemp ) ;
            *(p1++) = (unsigned char)nTemp;
        }
        // scanline pad is already clean
        p1 += nPad;
    }
}

//------------------------------------------------------------------------

bool RawBitmap::Rotate( int nAngle )
{
    sal_uLong nNewScanlineSize = 0;
    sal_uLong nNewHeight = 0;
    sal_uLong nNewWidth = 0;

    // do inplace rotation or prepare double buffered rotation
    switch( nAngle )
    {
        case 0:     // nothing to do
        case 3600:
            return true;
        default:    // non rectangular angles not allowed
            return false;
        case 1800:  // rotate by 180 degrees
            mnXOffset = -(mnXOffset + mnWidth);
            mnYOffset = -(mnYOffset + mnHeight);
            if( mnBitCount == 8 )
            {
                ImplRotate8_180( mpBits, mnWidth, mnHeight, mnScanlineSize-mnWidth );
                return true;
            }
            nNewWidth        = mnWidth;
            nNewHeight       = mnHeight;
            nNewScanlineSize = mnScanlineSize;
            break;
        case +900:  // left by 90 degrees
        case -900:
        case 2700:  // right by 90 degrees
            nNewWidth        = mnHeight;
            nNewHeight       = mnWidth;
            if( mnBitCount==1 )
                nNewScanlineSize = (nNewWidth + 7) / 8;
            else
                nNewScanlineSize = (nNewWidth + 3) & -4;
            break;
    }

    unsigned int nBufSize = nNewHeight * nNewScanlineSize;
    unsigned char* pBuf = new unsigned char[ nBufSize ];
    if( !pBuf )
        return false;
    
    memset( pBuf, 0, nBufSize );
    int i;

    // dispatch non-inplace rotations
    switch( nAngle )
    {
        case 1800:  // rotate by 180 degrees
            // we know we only need to deal with 1 bit depth
            ImplRotate1_180( pBuf, mpBits + mnHeight * mnScanlineSize,
                mnWidth, mnHeight, mnScanlineSize - (mnWidth + 7) / 8 );
            break;
        case +900:  // rotate left by 90 degrees
            i = mnXOffset;
            mnXOffset = mnYOffset;
            mnYOffset = -nNewHeight - i;
            if( mnBitCount == 8 )
                ImplRotate8_90( pBuf, mpBits + mnWidth - 1,
                    nNewWidth, nNewHeight, +mnScanlineSize, -1-mnHeight*mnScanlineSize,
                    nNewScanlineSize - nNewWidth );
            else
                ImplRotate1_90( pBuf, mpBits + (mnWidth - 1) / 8,
                    nNewWidth, nNewHeight, +mnScanlineSize,
                    (-mnWidth & 7), +1, nNewScanlineSize - (nNewWidth + 7) / 8 );
            break;
        case 2700:  // rotate right by 90 degrees
        case -900:
            i = mnXOffset;
            mnXOffset = -(nNewWidth + mnYOffset);
            mnYOffset = i;
            if( mnBitCount == 8 )
                ImplRotate8_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
                    nNewWidth, nNewHeight, -mnScanlineSize, +1+mnHeight*mnScanlineSize,
                    nNewScanlineSize - nNewWidth );
            else
                ImplRotate1_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
                    nNewWidth, nNewHeight, -mnScanlineSize,
                    +7, -1, nNewScanlineSize - (nNewWidth + 7) / 8 );
            break;
    }

    mnWidth        = nNewWidth;
    mnHeight       = nNewHeight;
    mnScanlineSize = nNewScanlineSize;

    if( nBufSize < mnAllocated )
    {
        memcpy( mpBits, pBuf, nBufSize );
        delete[] pBuf;
    }
    else
    {
        delete[] mpBits;
        mpBits = pBuf;
        mnAllocated = nBufSize;
    }

    return true;
}

//------------------------------------------------------------------------
