LCOV - code coverage report
Current view: top level - libreoffice/filter/source/graphicfilter/ipcd - ipcd.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 166 0.0 %
Date: 2012-12-17 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "rtl/alloc.h"
      22             : #include <vcl/graph.hxx>
      23             : #include <vcl/bmpacc.hxx>
      24             : #include <vcl/svapp.hxx>
      25             : #include <svtools/fltcall.hxx>
      26             : #include <svl/solar.hrc>
      27             : #include <svtools/FilterConfigItem.hxx>
      28             : 
      29             : //============================ PCDReader ==================================
      30             : 
      31             : // these resolutions are contained in a PCD file:
      32             : enum PCDResolution {
      33             :     PCDRES_BASE16,  //  192 x  128
      34             :     PCDRES_BASE4,   //  384 x  256
      35             :     PCDRES_BASE,    //  768 x  512
      36             :     // the following ones are compressed 
      37             :     // and CANNOT be read by us
      38             :     PCDRES_4BASE,   // 1536 x 1024
      39             :     PCDRES_16BASE   // 3072 x 3072
      40             : };
      41             : 
      42             : class PCDReader {
      43             : 
      44             : private:
      45             : 
      46             :     sal_Bool bStatus;
      47             : 
      48             :     sal_uLong               nLastPercent;
      49             : 
      50             :     SvStream &m_rPCD;
      51             :     BitmapWriteAccess*  mpAcc;
      52             : 
      53             :     sal_uInt8               nOrientation;   // orientation of the picture withinthe PCD file:
      54             :                                         // 0 - spire point up
      55             :                                         // 1 - spire points to the right
      56             :                                         // 2 - spire points down
      57             :                                         // 3 - spire points to the left
      58             : 
      59             :     PCDResolution       eResolution;    // which resolution we want
      60             : 
      61             :     sal_uLong               nWidth;         // width of the PCD picture
      62             :     sal_uLong               nHeight;        // heigth of the PCD picture
      63             :     sal_uLong               nImagePos;      // position of the picture within the PCD file
      64             : 
      65             :     // temporary lLue-Green-Red-Bitmap
      66             :     sal_uLong               nBMPWidth;
      67             :     sal_uLong               nBMPHeight;
      68             : 
      69             :     void    MayCallback(sal_uLong nPercent);
      70             : 
      71             :     void    CheckPCDImagePacFile();
      72             :         // checks whether it's a Photo-CD file with 'Image Pac'
      73             : 
      74             :     void    ReadOrientation();
      75             :         // reads the orientation and sets nOrientation
      76             : 
      77             :     void    ReadImage(sal_uLong nMinPercent, sal_uLong nMaxPercent);
      78             : 
      79             : public:
      80             : 
      81           0 :     PCDReader(SvStream &rStream)
      82           0 :         : m_rPCD(rStream)
      83             :     {
      84           0 :     }
      85           0 :     ~PCDReader() {}
      86             : 
      87             :     sal_Bool ReadPCD( Graphic & rGraphic, FilterConfigItem* pConfigItem );
      88             : };
      89             : 
      90             : //=================== Methods of PCDReader ==============================
      91             : 
      92           0 : sal_Bool PCDReader::ReadPCD( Graphic & rGraphic, FilterConfigItem* pConfigItem )
      93             : {
      94           0 :     Bitmap       aBmp;
      95             : 
      96           0 :     bStatus      = sal_True;
      97           0 :     nLastPercent = 0;
      98             : 
      99           0 :     MayCallback( 0 );
     100             : 
     101             :     // is it a PCD file with a picture? ( sets bStatus == sal_False, if that's not the case):
     102           0 :     CheckPCDImagePacFile();
     103             : 
     104             :     // read orientation of the picture:
     105           0 :     ReadOrientation();
     106             : 
     107             :     // which resolution do we want?:
     108           0 :     eResolution = PCDRES_BASE;
     109           0 :     if ( pConfigItem )
     110             :     {
     111           0 :         sal_Int32 nResolution = pConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), 2 );
     112           0 :         if ( nResolution == 1 )
     113           0 :             eResolution = PCDRES_BASE4;
     114           0 :         else if ( nResolution == 0 )
     115           0 :             eResolution = PCDRES_BASE16;
     116             :     }
     117             :     // determine size and position (position within the PCD file) of the picture:
     118           0 :     switch (eResolution)
     119             :     {
     120             :         case PCDRES_BASE16 :
     121           0 :             nWidth = 192;
     122           0 :             nHeight = 128;
     123           0 :             nImagePos = 8192;
     124           0 :             break;
     125             : 
     126             :         case PCDRES_BASE4 :
     127           0 :             nWidth = 384;
     128           0 :             nHeight = 256;
     129           0 :             nImagePos = 47104;
     130           0 :             break;
     131             : 
     132             :         case PCDRES_BASE :
     133           0 :             nWidth = 768;
     134           0 :             nHeight = 512;
     135           0 :             nImagePos = 196608;
     136           0 :             break;
     137             : 
     138             :         default:
     139           0 :             bStatus = sal_False;
     140             :     }
     141           0 :     if ( bStatus )
     142             :     {
     143           0 :         if ( ( nOrientation & 0x01 ) == 0 )
     144             :         {
     145           0 :             nBMPWidth = nWidth;
     146           0 :             nBMPHeight = nHeight;
     147             :         }
     148             :         else
     149             :         {
     150           0 :             nBMPWidth = nHeight;
     151           0 :             nBMPHeight = nWidth;
     152             :         }
     153           0 :         aBmp = Bitmap( Size( nBMPWidth, nBMPHeight ), 24 );
     154           0 :         if ( ( mpAcc = aBmp.AcquireWriteAccess() ) == sal_False )
     155           0 :             return sal_False;
     156             : 
     157           0 :         ReadImage( 5 ,65 );
     158             : 
     159           0 :         aBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
     160           0 :         rGraphic = aBmp;
     161             :     }
     162           0 :     return bStatus;
     163             : }
     164             : 
     165             : // -------------------------------------------------------------------------------------------
     166             : 
     167           0 : void PCDReader::MayCallback(sal_uLong /*nPercent*/)
     168             : {
     169           0 : }
     170             : 
     171             : // -------------------------------------------------------------------------------------------
     172             : 
     173           0 : void PCDReader::CheckPCDImagePacFile()
     174             : {
     175             :     char Buf[ 8 ];
     176             : 
     177           0 :     m_rPCD.Seek( 2048 );
     178           0 :     m_rPCD.Read( Buf, 7 );
     179           0 :     Buf[ 7 ] = 0;
     180           0 :     if (!rtl::OString(Buf).equalsL(RTL_CONSTASCII_STRINGPARAM("PCD_IPI")))
     181           0 :         bStatus = sal_False;
     182           0 : }
     183             : 
     184             : // -------------------------------------------------------------------------------------------
     185             : 
     186           0 : void PCDReader::ReadOrientation()
     187             : {
     188           0 :     if ( bStatus == sal_False )
     189           0 :         return;
     190           0 :     m_rPCD.Seek( 194635 );
     191           0 :     m_rPCD >> nOrientation;
     192           0 :     nOrientation &= 0x03;
     193             : }
     194             : 
     195             : // -------------------------------------------------------------------------------------------
     196             : 
     197           0 : void PCDReader::ReadImage(sal_uLong nMinPercent, sal_uLong nMaxPercent)
     198             : {
     199             :     sal_uLong  nx,ny,nW2,nH2,nYPair,ndy,nXPair;
     200             :     long   nL,nCb,nCr,nRed,nGreen,nBlue;
     201             :     sal_uInt8 * pt;
     202             :     sal_uInt8 * pL0; // luminance for each pixel of the 1st row of the current pair of rows
     203             :     sal_uInt8 * pL1; // luminance for each pixel of the 2nd row of the current pair of rows
     204             :     sal_uInt8 * pCb; // blue chrominance for each 2x2 pixel of the current pair of rows
     205             :     sal_uInt8 * pCr; // red chrominance fuer je 2x2 pixel of the current pair of rows
     206             :     sal_uInt8 * pL0N, * pL1N, * pCbN, * pCrN; // like above, but for the next pair of rows
     207             : 
     208           0 :     if ( bStatus == sal_False )
     209           0 :         return;
     210             : 
     211           0 :     nW2=nWidth>>1;
     212           0 :     nH2=nHeight>>1;
     213             : 
     214           0 :     pL0 =(sal_uInt8*)rtl_allocateMemory( nWidth );
     215           0 :     pL1 =(sal_uInt8*)rtl_allocateMemory( nWidth );
     216           0 :     pCb =(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     217           0 :     pCr =(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     218           0 :     pL0N=(sal_uInt8*)rtl_allocateMemory( nWidth );
     219           0 :     pL1N=(sal_uInt8*)rtl_allocateMemory( nWidth );
     220           0 :     pCbN=(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     221           0 :     pCrN=(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     222             : 
     223           0 :     if ( pL0 == NULL || pL1 == NULL || pCb == NULL || pCr == NULL ||
     224             :         pL0N == NULL || pL1N == NULL || pCbN == NULL || pCrN == NULL)
     225             :     {
     226           0 :         rtl_freeMemory((void*)pL0 );
     227           0 :         rtl_freeMemory((void*)pL1 );
     228           0 :         rtl_freeMemory((void*)pCb );
     229           0 :         rtl_freeMemory((void*)pCr );
     230           0 :         rtl_freeMemory((void*)pL0N);
     231           0 :         rtl_freeMemory((void*)pL1N);
     232           0 :         rtl_freeMemory((void*)pCbN);
     233           0 :         rtl_freeMemory((void*)pCrN);
     234           0 :         bStatus = sal_False;
     235           0 :         return;
     236             :     }
     237             : 
     238           0 :     m_rPCD.Seek( nImagePos );
     239             : 
     240             :     // next pair of rows := first pair of rows:
     241           0 :     m_rPCD.Read( pL0N, nWidth );
     242           0 :     m_rPCD.Read( pL1N, nWidth );
     243           0 :     m_rPCD.Read( pCbN, nW2 );
     244           0 :     m_rPCD.Read( pCrN, nW2 );
     245           0 :     pCbN[ nW2 ] = pCbN[ nW2 - 1 ];
     246           0 :     pCrN[ nW2 ] = pCrN[ nW2 - 1 ];
     247             : 
     248           0 :     for ( nYPair = 0; nYPair < nH2; nYPair++ )
     249             :     {
     250             :         // current pair of rows := next pair of rows:
     251           0 :         pt=pL0; pL0=pL0N; pL0N=pt;
     252           0 :         pt=pL1; pL1=pL1N; pL1N=pt;
     253           0 :         pt=pCb; pCb=pCbN; pCbN=pt;
     254           0 :         pt=pCr; pCr=pCrN; pCrN=pt;
     255             : 
     256             :         // get the next pair of rows:
     257           0 :         if ( nYPair < nH2 - 1 )
     258             :         {
     259           0 :             m_rPCD.Read( pL0N, nWidth );
     260           0 :             m_rPCD.Read( pL1N, nWidth );
     261           0 :             m_rPCD.Read( pCbN, nW2 );
     262           0 :             m_rPCD.Read( pCrN, nW2 );
     263           0 :             pCbN[nW2]=pCbN[ nW2 - 1 ];
     264           0 :             pCrN[nW2]=pCrN[ nW2 - 1 ];
     265             :         }
     266             :         else
     267             :         {
     268           0 :             for ( nXPair = 0; nXPair < nW2; nXPair++ )
     269             :             {
     270           0 :                 pCbN[ nXPair ] = pCb[ nXPair ];
     271           0 :                 pCrN[ nXPair ] = pCr[ nXPair ];
     272             :             }
     273             :         }
     274             : 
     275             :         // loop trough both rows of the pair of rows:
     276           0 :         for ( ndy = 0; ndy < 2; ndy++ )
     277             :         {
     278           0 :             ny = ( nYPair << 1 ) + ndy;
     279             : 
     280             :             // loop trough X:
     281           0 :             for ( nx = 0; nx < nWidth; nx++ )
     282             :             {
     283             :                 // get/calculate nL,nCb,nCr for the pixel nx,ny:
     284           0 :                 nXPair = nx >> 1;
     285           0 :                 if ( ndy == 0 )
     286             :                 {
     287           0 :                     nL = (long)pL0[ nx ];
     288           0 :                     if (( nx & 1 ) == 0 )
     289             :                     {
     290           0 :                         nCb = (long)pCb[ nXPair ];
     291           0 :                         nCr = (long)pCr[ nXPair ];
     292             :                     }
     293             :                     else
     294             :                     {
     295           0 :                         nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) ) >> 1;
     296           0 :                         nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1 ] ) ) >> 1;
     297             :                     }
     298             :                 }
     299             :                 else {
     300           0 :                     nL = pL1[ nx ];
     301           0 :                     if ( ( nx & 1 ) == 0 )
     302             :                     {
     303           0 :                         nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCbN[ nXPair ] ) ) >> 1;
     304           0 :                         nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCrN[ nXPair ] ) ) >> 1;
     305             :                     }
     306             :                     else
     307             :                     {
     308           0 :                         nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) +
     309           0 :                                ( (long)pCbN[ nXPair ] ) + ( (long)pCbN[ nXPair + 1 ] ) ) >> 2;
     310           0 :                         nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1] ) +
     311           0 :                                ( (long)pCrN[ nXPair ] ) + ( (long)pCrN[ nXPair + 1 ] ) ) >> 2;
     312             :                     }
     313             :                 }
     314             :                 // Umwandlung von nL,nCb,nCr in nRed,nGreen,nBlue:
     315           0 :                 nL *= 89024L;
     316           0 :                 nCb -= 156;
     317           0 :                 nCr -= 137;
     318           0 :                 nRed = ( nL + nCr * 119374L + 0x8000 ) >> 16;
     319           0 :                 if ( nRed < 0 )
     320           0 :                     nRed = 0;
     321           0 :                 if ( nRed > 255)
     322           0 :                     nRed = 255;
     323           0 :                 nGreen = ( nL - nCb * 28198L - nCr * 60761L + 0x8000 ) >> 16;
     324           0 :                 if ( nGreen < 0 )
     325           0 :                     nGreen = 0;
     326           0 :                 if ( nGreen > 255 )
     327           0 :                     nGreen = 255;
     328           0 :                 nBlue = ( nL + nCb * 145352L + 0x8000 ) >> 16;
     329           0 :                 if ( nBlue < 0 )
     330           0 :                     nBlue = 0;
     331           0 :                 if ( nBlue > 255 )
     332           0 :                     nBlue = 255;
     333             : 
     334             :                 // register color value in pBMPMap:
     335           0 :                 if ( nOrientation < 2 )
     336             :                 {
     337           0 :                     if ( nOrientation == 0 )
     338           0 :                         mpAcc->SetPixel( ny, nx, BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     339             :                     else
     340           0 :                         mpAcc->SetPixel( nWidth - 1 - nx, ny, BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     341             :                 }
     342             :                 else
     343             :                 {
     344           0 :                     if ( nOrientation == 2 )
     345           0 :                         mpAcc->SetPixel( nHeight - 1 - ny, ( nWidth - 1 - nx ), BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     346             :                     else
     347           0 :                         mpAcc->SetPixel( nx, ( nHeight - 1 - ny ), BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     348             :                 }
     349             :             }
     350             :         }
     351             : 
     352           0 :         if ( m_rPCD.GetError() )
     353           0 :             bStatus = sal_False;
     354           0 :         MayCallback( nMinPercent + ( nMaxPercent - nMinPercent ) * nYPair / nH2 );
     355           0 :         if ( bStatus == sal_False )
     356           0 :             break;
     357             :     }
     358           0 :     rtl_freeMemory((void*)pL0 );
     359           0 :     rtl_freeMemory((void*)pL1 );
     360           0 :     rtl_freeMemory((void*)pCb );
     361           0 :     rtl_freeMemory((void*)pCr );
     362           0 :     rtl_freeMemory((void*)pL0N);
     363           0 :     rtl_freeMemory((void*)pL1N);
     364           0 :     rtl_freeMemory((void*)pCbN);
     365           0 :     rtl_freeMemory((void*)pCrN);
     366             : }
     367             : 
     368             : //================== GraphicImport - the exported Function ================
     369             : 
     370             : #ifdef DISABLE_DYNLOADING
     371             : #define GraphicImport icdGraphicImport
     372             : #endif
     373             : 
     374             : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
     375           0 : GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pConfigItem, sal_Bool)
     376             : {
     377           0 :     PCDReader aPCDReader(rStream);
     378           0 :     return aPCDReader.ReadPCD(rGraphic, pConfigItem);
     379             : }
     380             : 
     381             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10