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

Generated by: LCOV version 1.11