LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipcd - ipcd.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 0 167 0.0 %
Date: 2014-11-03 Functions: 0 9 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 <vcl/fltcall.hxx>
      26             : #include <svl/solar.hrc>
      27             : #include <vcl/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             :     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;        // height 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             :         : bStatus(false)
      83             :         , nLastPercent(0)
      84             :         , m_rPCD(rStream)
      85             :         , mpAcc(NULL)
      86             :         , nOrientation(0)
      87             :         , eResolution(PCDRES_BASE16)
      88             :         , nWidth(0)
      89             :         , nHeight(0)
      90             :         , nImagePos(0)
      91             :         , nBMPWidth(0)
      92           0 :         , nBMPHeight(0)
      93             :     {
      94           0 :     }
      95             : 
      96             :     bool ReadPCD( Graphic & rGraphic, FilterConfigItem* pConfigItem );
      97             : };
      98             : 
      99             : //=================== Methods of PCDReader ==============================
     100             : 
     101           0 : bool PCDReader::ReadPCD( Graphic & rGraphic, FilterConfigItem* pConfigItem )
     102             : {
     103           0 :     Bitmap       aBmp;
     104             : 
     105           0 :     bStatus      = true;
     106           0 :     nLastPercent = 0;
     107             : 
     108           0 :     MayCallback( 0 );
     109             : 
     110             :     // is it a PCD file with a picture? ( sets bStatus == sal_False, if that's not the case):
     111           0 :     CheckPCDImagePacFile();
     112             : 
     113             :     // read orientation of the picture:
     114           0 :     ReadOrientation();
     115             : 
     116             :     // which resolution do we want?:
     117           0 :     eResolution = PCDRES_BASE;
     118           0 :     if ( pConfigItem )
     119             :     {
     120           0 :         sal_Int32 nResolution = pConfigItem->ReadInt32( "Resolution", 2 );
     121           0 :         if ( nResolution == 1 )
     122           0 :             eResolution = PCDRES_BASE4;
     123           0 :         else if ( nResolution == 0 )
     124           0 :             eResolution = PCDRES_BASE16;
     125             :     }
     126             :     // determine size and position (position within the PCD file) of the picture:
     127           0 :     switch (eResolution)
     128             :     {
     129             :         case PCDRES_BASE16 :
     130           0 :             nWidth = 192;
     131           0 :             nHeight = 128;
     132           0 :             nImagePos = 8192;
     133           0 :             break;
     134             : 
     135             :         case PCDRES_BASE4 :
     136           0 :             nWidth = 384;
     137           0 :             nHeight = 256;
     138           0 :             nImagePos = 47104;
     139           0 :             break;
     140             : 
     141             :         case PCDRES_BASE :
     142           0 :             nWidth = 768;
     143           0 :             nHeight = 512;
     144           0 :             nImagePos = 196608;
     145           0 :             break;
     146             : 
     147             :         default:
     148           0 :             bStatus = false;
     149             :     }
     150           0 :     if ( bStatus )
     151             :     {
     152           0 :         if ( ( nOrientation & 0x01 ) == 0 )
     153             :         {
     154           0 :             nBMPWidth = nWidth;
     155           0 :             nBMPHeight = nHeight;
     156             :         }
     157             :         else
     158             :         {
     159           0 :             nBMPWidth = nHeight;
     160           0 :             nBMPHeight = nWidth;
     161             :         }
     162           0 :         aBmp = Bitmap( Size( nBMPWidth, nBMPHeight ), 24 );
     163           0 :         if ( ( mpAcc = aBmp.AcquireWriteAccess() ) == 0 )
     164           0 :             return false;
     165             : 
     166           0 :         ReadImage( 5 ,65 );
     167             : 
     168           0 :         aBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
     169           0 :         rGraphic = aBmp;
     170             :     }
     171           0 :     return bStatus;
     172             : }
     173             : 
     174             : 
     175             : 
     176           0 : void PCDReader::MayCallback(sal_uLong /*nPercent*/)
     177             : {
     178           0 : }
     179             : 
     180             : 
     181             : 
     182           0 : void PCDReader::CheckPCDImagePacFile()
     183             : {
     184             :     char Buf[ 8 ];
     185             : 
     186           0 :     m_rPCD.Seek( 2048 );
     187           0 :     m_rPCD.Read( Buf, 7 );
     188           0 :     Buf[ 7 ] = 0;
     189           0 :     if (OString(Buf) != "PCD_IPI")
     190           0 :         bStatus = false;
     191           0 : }
     192             : 
     193             : 
     194             : 
     195           0 : void PCDReader::ReadOrientation()
     196             : {
     197           0 :     if ( bStatus == false )
     198           0 :         return;
     199           0 :     m_rPCD.Seek( 194635 );
     200           0 :     m_rPCD.ReadUChar( nOrientation );
     201           0 :     nOrientation &= 0x03;
     202             : }
     203             : 
     204             : 
     205             : 
     206           0 : void PCDReader::ReadImage(sal_uLong nMinPercent, sal_uLong nMaxPercent)
     207             : {
     208             :     sal_uLong  nx,ny,nW2,nH2,nYPair,ndy,nXPair;
     209             :     long   nL,nCb,nCr,nRed,nGreen,nBlue;
     210             :     sal_uInt8 * pt;
     211             :     sal_uInt8 * pL0; // luminance for each pixel of the 1st row of the current pair of rows
     212             :     sal_uInt8 * pL1; // luminance for each pixel of the 2nd row of the current pair of rows
     213             :     sal_uInt8 * pCb; // blue chrominance for each 2x2 pixel of the current pair of rows
     214             :     sal_uInt8 * pCr; // red chrominance fuer je 2x2 pixel of the current pair of rows
     215             :     sal_uInt8 * pL0N, * pL1N, * pCbN, * pCrN; // like above, but for the next pair of rows
     216             : 
     217           0 :     if ( bStatus == false )
     218           0 :         return;
     219             : 
     220           0 :     nW2=nWidth>>1;
     221           0 :     nH2=nHeight>>1;
     222             : 
     223           0 :     pL0 =(sal_uInt8*)rtl_allocateMemory( nWidth );
     224           0 :     pL1 =(sal_uInt8*)rtl_allocateMemory( nWidth );
     225           0 :     pCb =(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     226           0 :     pCr =(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     227           0 :     pL0N=(sal_uInt8*)rtl_allocateMemory( nWidth );
     228           0 :     pL1N=(sal_uInt8*)rtl_allocateMemory( nWidth );
     229           0 :     pCbN=(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     230           0 :     pCrN=(sal_uInt8*)rtl_allocateMemory( nW2+1 );
     231             : 
     232           0 :     if ( pL0 == NULL || pL1 == NULL || pCb == NULL || pCr == NULL ||
     233           0 :         pL0N == NULL || pL1N == NULL || pCbN == NULL || pCrN == NULL)
     234             :     {
     235           0 :         rtl_freeMemory((void*)pL0 );
     236           0 :         rtl_freeMemory((void*)pL1 );
     237           0 :         rtl_freeMemory((void*)pCb );
     238           0 :         rtl_freeMemory((void*)pCr );
     239           0 :         rtl_freeMemory((void*)pL0N);
     240           0 :         rtl_freeMemory((void*)pL1N);
     241           0 :         rtl_freeMemory((void*)pCbN);
     242           0 :         rtl_freeMemory((void*)pCrN);
     243           0 :         bStatus = false;
     244           0 :         return;
     245             :     }
     246             : 
     247           0 :     m_rPCD.Seek( nImagePos );
     248             : 
     249             :     // next pair of rows := first pair of rows:
     250           0 :     m_rPCD.Read( pL0N, nWidth );
     251           0 :     m_rPCD.Read( pL1N, nWidth );
     252           0 :     m_rPCD.Read( pCbN, nW2 );
     253           0 :     m_rPCD.Read( pCrN, nW2 );
     254           0 :     pCbN[ nW2 ] = pCbN[ nW2 - 1 ];
     255           0 :     pCrN[ nW2 ] = pCrN[ nW2 - 1 ];
     256             : 
     257           0 :     for ( nYPair = 0; nYPair < nH2; nYPair++ )
     258             :     {
     259             :         // current pair of rows := next pair of rows:
     260           0 :         pt=pL0; pL0=pL0N; pL0N=pt;
     261           0 :         pt=pL1; pL1=pL1N; pL1N=pt;
     262           0 :         pt=pCb; pCb=pCbN; pCbN=pt;
     263           0 :         pt=pCr; pCr=pCrN; pCrN=pt;
     264             : 
     265             :         // get the next pair of rows:
     266           0 :         if ( nYPair < nH2 - 1 )
     267             :         {
     268           0 :             m_rPCD.Read( pL0N, nWidth );
     269           0 :             m_rPCD.Read( pL1N, nWidth );
     270           0 :             m_rPCD.Read( pCbN, nW2 );
     271           0 :             m_rPCD.Read( pCrN, nW2 );
     272           0 :             pCbN[nW2]=pCbN[ nW2 - 1 ];
     273           0 :             pCrN[nW2]=pCrN[ nW2 - 1 ];
     274             :         }
     275             :         else
     276             :         {
     277           0 :             for ( nXPair = 0; nXPair < nW2; nXPair++ )
     278             :             {
     279           0 :                 pCbN[ nXPair ] = pCb[ nXPair ];
     280           0 :                 pCrN[ nXPair ] = pCr[ nXPair ];
     281             :             }
     282             :         }
     283             : 
     284             :         // loop trough both rows of the pair of rows:
     285           0 :         for ( ndy = 0; ndy < 2; ndy++ )
     286             :         {
     287           0 :             ny = ( nYPair << 1 ) + ndy;
     288             : 
     289             :             // loop trough X:
     290           0 :             for ( nx = 0; nx < nWidth; nx++ )
     291             :             {
     292             :                 // get/calculate nL,nCb,nCr for the pixel nx,ny:
     293           0 :                 nXPair = nx >> 1;
     294           0 :                 if ( ndy == 0 )
     295             :                 {
     296           0 :                     nL = (long)pL0[ nx ];
     297           0 :                     if (( nx & 1 ) == 0 )
     298             :                     {
     299           0 :                         nCb = (long)pCb[ nXPair ];
     300           0 :                         nCr = (long)pCr[ nXPair ];
     301             :                     }
     302             :                     else
     303             :                     {
     304           0 :                         nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) ) >> 1;
     305           0 :                         nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1 ] ) ) >> 1;
     306             :                     }
     307             :                 }
     308             :                 else {
     309           0 :                     nL = pL1[ nx ];
     310           0 :                     if ( ( nx & 1 ) == 0 )
     311             :                     {
     312           0 :                         nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCbN[ nXPair ] ) ) >> 1;
     313           0 :                         nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCrN[ nXPair ] ) ) >> 1;
     314             :                     }
     315             :                     else
     316             :                     {
     317           0 :                         nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) +
     318           0 :                                ( (long)pCbN[ nXPair ] ) + ( (long)pCbN[ nXPair + 1 ] ) ) >> 2;
     319           0 :                         nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1] ) +
     320           0 :                                ( (long)pCrN[ nXPair ] ) + ( (long)pCrN[ nXPair + 1 ] ) ) >> 2;
     321             :                     }
     322             :                 }
     323             :                 // conversion of nL,nCb,nCr in nRed,nGreen,nBlue:
     324           0 :                 nL *= 89024L;
     325           0 :                 nCb -= 156;
     326           0 :                 nCr -= 137;
     327           0 :                 nRed = ( nL + nCr * 119374L + 0x8000 ) >> 16;
     328           0 :                 if ( nRed < 0 )
     329           0 :                     nRed = 0;
     330           0 :                 if ( nRed > 255)
     331           0 :                     nRed = 255;
     332           0 :                 nGreen = ( nL - nCb * 28198L - nCr * 60761L + 0x8000 ) >> 16;
     333           0 :                 if ( nGreen < 0 )
     334           0 :                     nGreen = 0;
     335           0 :                 if ( nGreen > 255 )
     336           0 :                     nGreen = 255;
     337           0 :                 nBlue = ( nL + nCb * 145352L + 0x8000 ) >> 16;
     338           0 :                 if ( nBlue < 0 )
     339           0 :                     nBlue = 0;
     340           0 :                 if ( nBlue > 255 )
     341           0 :                     nBlue = 255;
     342             : 
     343             :                 // register color value in pBMPMap:
     344           0 :                 if ( nOrientation < 2 )
     345             :                 {
     346           0 :                     if ( nOrientation == 0 )
     347           0 :                         mpAcc->SetPixel( ny, nx, BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     348             :                     else
     349           0 :                         mpAcc->SetPixel( nWidth - 1 - nx, ny, BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     350             :                 }
     351             :                 else
     352             :                 {
     353           0 :                     if ( nOrientation == 2 )
     354           0 :                         mpAcc->SetPixel( nHeight - 1 - ny, ( nWidth - 1 - nx ), BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     355             :                     else
     356           0 :                         mpAcc->SetPixel( nx, ( nHeight - 1 - ny ), BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     357             :                 }
     358             :             }
     359             :         }
     360             : 
     361           0 :         if ( m_rPCD.GetError() )
     362           0 :             bStatus = false;
     363           0 :         MayCallback( nMinPercent + ( nMaxPercent - nMinPercent ) * nYPair / nH2 );
     364           0 :         if ( bStatus == false )
     365           0 :             break;
     366             :     }
     367           0 :     rtl_freeMemory((void*)pL0 );
     368           0 :     rtl_freeMemory((void*)pL1 );
     369           0 :     rtl_freeMemory((void*)pCb );
     370           0 :     rtl_freeMemory((void*)pCr );
     371           0 :     rtl_freeMemory((void*)pL0N);
     372           0 :     rtl_freeMemory((void*)pL1N);
     373           0 :     rtl_freeMemory((void*)pCbN);
     374           0 :     rtl_freeMemory((void*)pCrN);
     375             : }
     376             : 
     377             : //================== GraphicImport - the exported Function ================
     378             : 
     379             : // this needs to be kept in sync with
     380             : // ImpFilterLibCacheEntry::GetImportFunction() from
     381             : // vcl/source/filter/graphicfilter.cxx
     382             : #if defined(DISABLE_DYNLOADING)
     383             : #define GraphicImport icdGraphicImport
     384             : #endif
     385             : 
     386             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
     387           0 : GraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pConfigItem )
     388             : {
     389           0 :     PCDReader aPCDReader(rStream);
     390           0 :     return aPCDReader.ReadPCD(rGraphic, pConfigItem);
     391           0 : }
     392             : 
     393             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10