LCOV - code coverage report
Current view: top level - gutils - gimagereadbmp.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 297 0.0 %
Date: 2017-08-04 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2000-2012 by George Williams */
       2             : /*
       3             :  * Redistribution and use in source and binary forms, with or without
       4             :  * modification, are permitted provided that the following conditions are met:
       5             : 
       6             :  * Redistributions of source code must retain the above copyright notice, this
       7             :  * list of conditions and the following disclaimer.
       8             : 
       9             :  * Redistributions in binary form must reproduce the above copyright notice,
      10             :  * this list of conditions and the following disclaimer in the documentation
      11             :  * and/or other materials provided with the distribution.
      12             : 
      13             :  * The name of the author may not be used to endorse or promote products
      14             :  * derived from this software without specific prior written permission.
      15             : 
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
      17             :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      18             :  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
      19             :  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      20             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      21             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
      22             :  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      23             :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      24             :  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
      25             :  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : #include "gimage.h"
      28             : #include "gimagebmpP.h"
      29             : #include <string.h>
      30             : GImage *_GImage_Create(enum image_type type, int32 width, int32 height);
      31             : 
      32           0 : static int getshort(FILE *fp) {
      33             : /* Get Little-Endian short 16bit value. Return value if okay, -1 if error */
      34             :     int ch1, ch2;
      35             : 
      36           0 :     if ( (ch1=fgetc(fp))<0 || (ch2=fgetc(fp))<0 )
      37           0 :         return( -1 );
      38             : 
      39           0 :     return( (ch2<<8) | ch1 );
      40             : }
      41             : 
      42           0 : static long getlong(FILE *fp, long *value) {
      43             : /* Get Little-Endian long 32bit int value. Return 0 if okay, -1 if error. */
      44             :     int ch1, ch2, ch3, ch4;
      45             : 
      46           0 :     if ( (ch1=fgetc(fp))<0 || (ch2=fgetc(fp))<0 || \
      47           0 :          (ch3=fgetc(fp))<0 || (ch4=fgetc(fp))<0 ) {
      48           0 :         *value=0;
      49           0 :         return( -1 );
      50             :     }
      51           0 :     *value=(long)( (ch4<<24)|(ch3<<16)|(ch2<<8)|ch1 );
      52           0 :     return( 0 );
      53             : }
      54             : 
      55           0 : static int bitshift(unsigned long mask) {
      56           0 :     int off=0, len=0, bit;
      57             : 
      58           0 :     if ( mask==0 )
      59           0 : return( 0 );
      60           0 :     for ( off=0; !(mask&1); mask>>=1, ++off );
      61           0 :     for ( len=0, bit=1; (mask&bit) && len<32; ++len, bit<<=1 );
      62           0 : return( off+(8-len) );
      63             : }
      64             : 
      65           0 : static int fillbmpheader(FILE *fp,struct bmpheader *head) {
      66             : /* Get BMPheader info. Return 0 if read the header okay, -1 if read error */
      67             :     int i;
      68             :     long temp;
      69             : 
      70           0 :     if ( fgetc(fp)!='B' || getc(fp)!='M' ||     /* Bad format */ \
      71           0 :          getlong(fp,&head->size) || \
      72           0 :          (head->mbz1=getshort(fp))<0      || \
      73           0 :          (head->mbz2=getshort(fp))<0      || \
      74           0 :          getlong(fp,&head->offset)       || \
      75           0 :          getlong(fp,&head->headersize)   )
      76           0 :         return( -1 );
      77             : 
      78           0 :     if ( head->headersize==12 ) {    /* Windows 2.0 format, also OS/2 */
      79           0 :         if ( (head->width=getshort(fp))<0 || \
      80           0 :              (head->height=getshort(fp))<0        || \
      81           0 :              (head->planes=getshort(fp))<0        || \
      82           0 :              (head->bitsperpixel=getshort(fp))<0 )
      83           0 :             return( -1 );
      84             :         //head->colorsused=0;
      85             :         //head->compression=0;
      86             :     } else {
      87           0 :         if ( getlong(fp,&head->width)            || \
      88           0 :              getlong(fp,&head->height)           || \
      89           0 :              (head->planes=getshort(fp))<0        || \
      90           0 :              (head->bitsperpixel=getshort(fp))<0 || \
      91           0 :              getlong(fp,&head->compression)      || \
      92           0 :              getlong(fp,&head->imagesize)        || \
      93           0 :              getlong(fp,&head->ignore1)          || \
      94           0 :              getlong(fp,&head->ignore2)          || \
      95           0 :              getlong(fp,&head->colorsused)       || \
      96           0 :              getlong(fp,&head->colorsimportant) )
      97           0 :             return( -1 );
      98             :     }
      99           0 :     if ( head->height<0 )
     100           0 :         head->height = -head->height;
     101             :     else
     102           0 :         head->invert = true;
     103             : 
     104           0 :     if ( head->bitsperpixel!=1 && head->bitsperpixel!=4 && head->bitsperpixel!=8 &&
     105           0 :             head->bitsperpixel!=16 && head->bitsperpixel!=24 && head->bitsperpixel!=32 )
     106           0 :         return( -1 );
     107             : 
     108           0 :     if ( head->compression==3 && ( head->bitsperpixel==16 || head->bitsperpixel==32 ) )
     109             :         /* Good */;
     110           0 :     else if ( head->compression==0 && ( head->bitsperpixel<=8 || head->bitsperpixel==24 || head->bitsperpixel==32 ) )
     111             :         /* Good */;
     112           0 :     else if ( head->compression==1 && head->bitsperpixel==8 )
     113             :         /* Good */;
     114           0 :     else if ( head->compression==2 && head->bitsperpixel==4 )
     115             :         /* Good */;
     116             :     else
     117           0 :         return( -1 );
     118             : 
     119           0 :     if ( head->colorsused==0 )
     120           0 :         head->colorsused = 1<<head->bitsperpixel;
     121           0 :     if ( head->bitsperpixel>=16 )
     122           0 :         head->colorsused = 0;
     123           0 :     if ( head->colorsused>(1<<head->bitsperpixel) )
     124           0 :         return( -1 );
     125             : 
     126           0 :     for ( i=0; i<head->colorsused; ++i ) {
     127             :         int b,g,r;
     128           0 :         if ( (b=fgetc(fp))<0 || (g=fgetc(fp))<0 || (r=fgetc(fp))<0 )
     129           0 :             return( -1 );
     130           0 :         head->clut[i]=COLOR_CREATE(r,g,b);
     131           0 :         if ( head->headersize!=12 && fgetc(fp)<0 )
     132           0 :             return( -1 );
     133             :     }
     134           0 :     if ( head->compression==3 || head->headersize==108 ) {
     135           0 :         if ( getlong(fp,&head->red_mask) || \
     136           0 :              getlong(fp,&head->green_mask)       || \
     137           0 :              getlong(fp,&head->blue_mask) )
     138           0 :             return( -1 );
     139           0 :         head->red_shift = bitshift(head->red_mask);
     140           0 :         head->green_shift = bitshift(head->green_mask);
     141           0 :         head->blue_shift = bitshift(head->blue_mask);
     142             :     }
     143             : 
     144           0 :     if ( head->headersize==108 && (
     145           0 :          getlong(fp,&temp) ||       /* alpha_mask */ \
     146           0 :          getlong(fp,&temp) ||       /* color space type */ \
     147           0 :          getlong(fp,&temp) ||       /* redx */ \
     148           0 :          getlong(fp,&temp) ||       /* redy */ \
     149           0 :          getlong(fp,&temp) ||       /* redz */ \
     150           0 :          getlong(fp,&temp) ||       /* greenx */ \
     151           0 :          getlong(fp,&temp) ||       /* greeny */ \
     152           0 :          getlong(fp,&temp) ||       /* greenz */ \
     153           0 :          getlong(fp,&temp) ||       /* bluex */ \
     154           0 :          getlong(fp,&temp) ||       /* bluey */ \
     155           0 :          getlong(fp,&temp) ||       /* bluez */ \
     156           0 :          getlong(fp,&temp) ||       /* gammared */ \
     157           0 :          getlong(fp,&temp) ||       /* gammagreen */ \
     158           0 :          getlong(fp,&temp) )        /* gammablue */ )
     159           0 :         return( -1 );
     160             : 
     161           0 :     return( 0 );
     162             : }
     163             : 
     164           0 : static int readpixels(FILE *file,struct bmpheader *head) {
     165             :     int i,ii,j,ll,excess;
     166             : 
     167           0 :     fseek(file,head->offset,0);
     168             : 
     169           0 :     ll = head->width;
     170           0 :     if ( head->bitsperpixel==8 && head->compression==0 ) {
     171           0 :         excess = ((ll+3)/4)*4 -ll;
     172           0 :         for ( i=0; i<head->height; ++i ) {
     173           0 :             fread(head->byte_pixels+i*ll,1,ll,file);
     174           0 :             for ( j=0; j<excess; ++j )
     175           0 :                 (void) getc(file);
     176             :         }
     177           0 :     } else if ( head->bitsperpixel==8 ) {
     178             :         /* 8 bit RLE */
     179           0 :         int ii = 0;
     180           0 :         while ( ii<head->height*head->width ) {
     181           0 :             int cnt = getc(file);
     182           0 :             if ( cnt!=0 ) {
     183           0 :                 int ch = getc(file);
     184           0 :                 while ( --cnt>=0 )
     185           0 :                     head->byte_pixels[ii++] = ch;
     186             :             } else {
     187           0 :                 cnt = getc(file);
     188           0 :                 if ( cnt>= 3 ) {
     189           0 :                     int odd = cnt&1;
     190           0 :                     while ( --cnt>=0 )
     191           0 :                         head->byte_pixels[ii++] = getc(file);
     192           0 :                     if ( odd )
     193           0 :                         getc(file);
     194           0 :                 } else if ( cnt==0 ) {  /* end of scan line */
     195           0 :                     ii = ((ii+head->width-1)/head->width) * head->width;
     196           0 :                 } else if ( cnt==1 ) {
     197           0 :         break;
     198           0 :                 } else if ( cnt==2 ) {
     199           0 :                     int x=getc(file);
     200           0 :                     int y = getc(file);
     201           0 :                     y += ii/head->width;
     202           0 :                     x += ii%head->width;
     203           0 :                     ii = y*head->width + x;
     204             :                 }
     205             :             }
     206             :         }
     207           0 :     } else if ( head->bitsperpixel==4 && head->compression==0 ) {
     208           0 :         excess = (ll+1)/2;
     209           0 :         excess = ((excess+3)/4)*4 -excess;
     210           0 :         for ( i=0; i<head->height; ++i ) {
     211           0 :             ii = i*ll;
     212           0 :             for ( j=0; j<((head->width+7)/8)*8; j+=8 ) {
     213           0 :                 int b1 = getc(file);
     214           0 :                 int b2 = getc(file);
     215           0 :                 int b3 = getc(file);
     216           0 :                 int b4 = getc(file);
     217           0 :                 head->byte_pixels[ii+j] = (b1>>4);
     218           0 :                 if ( j+1<ll ) head->byte_pixels[ii+j+1] = (b1&0xf);
     219           0 :                 if ( j+2<ll ) head->byte_pixels[ii+j+2] = (b2>>4);
     220           0 :                 if ( j+3<ll ) head->byte_pixels[ii+j+3] = (b2&0xf);
     221           0 :                 if ( j+4<ll ) head->byte_pixels[ii+j+4] = (b3>>4);
     222           0 :                 if ( j+5<ll ) head->byte_pixels[ii+j+5] = (b3&0xf);
     223           0 :                 if ( j+6<ll ) head->byte_pixels[ii+j+6] = (b4>>4);
     224           0 :                 if ( j+7<ll ) head->byte_pixels[ii+j+7] = (b4&0xf);
     225             :             }
     226           0 :             for ( j=0; j<excess; ++j )
     227           0 :                 (void) getc(file);
     228             :         }
     229           0 :     } else if ( head->bitsperpixel==4 ) {
     230             :         /* 4 bit RLE */
     231           0 :         int ii = 0;
     232           0 :         while ( ii<head->height*head->width ) {
     233           0 :             int cnt = getc(file);
     234           0 :             if ( cnt!=0 ) {
     235           0 :                 int ch = getc(file);
     236           0 :                 while ( (cnt-=2)>=-1 ) {
     237           0 :                     head->byte_pixels[ii++] = ch>>4;
     238           0 :                     head->byte_pixels[ii++] = ch&0xf;
     239             :                 }
     240           0 :                 if ( cnt==-1 ) --ii;
     241             :             } else {
     242           0 :                 cnt = getc(file);
     243           0 :                 if ( cnt>= 3 ) {
     244           0 :                     int odd = cnt&2;
     245           0 :                     while ( (cnt-=2)>=-1 ) {
     246           0 :                         int ch = getc(file);
     247           0 :                         head->byte_pixels[ii++] = ch>>4;
     248           0 :                         head->byte_pixels[ii++] = ch&0xf;
     249             :                     }
     250           0 :                     if ( cnt==-1 ) --ii;
     251           0 :                     if ( odd )
     252           0 :                         getc(file);
     253           0 :                 } else if ( cnt==0 ) {  /* end of scan line */
     254           0 :                     ii = ((ii+head->width-1)/head->width) * head->width;
     255           0 :                 } else if ( cnt==1 ) {
     256           0 :         break;
     257           0 :                 } else if ( cnt==2 ) {
     258           0 :                     int x=getc(file);
     259           0 :                     int y = getc(file);
     260           0 :                     y += ii/head->width;
     261           0 :                     x += ii%head->width;
     262           0 :                     ii = y*head->width + x;
     263             :                 }
     264             :             }
     265             :         }
     266           0 :     } else if ( head->bitsperpixel==1 ) {
     267           0 :         excess = (ll+7)/8;
     268           0 :         excess = ((excess+3)/4)*4 -excess;
     269           0 :         for ( i=0; i<head->height; ++i ) {
     270           0 :             ii = i*((ll+7)/8);
     271           0 :             for ( j=0; j<((head->width+7)/8); ++j ) {
     272           0 :                 head->byte_pixels[ii+j] = getc(file);
     273             :             }
     274           0 :             for ( j=0; j<excess; ++j )
     275           0 :                 (void) getc(file);
     276             :         }
     277           0 :     } else if ( head->bitsperpixel==24 ) {
     278           0 :         excess = ((3*head->width+3)/4)*4 - 3*head->width;
     279           0 :         for ( i=0; i<head->height; ++i ) {
     280           0 :             ii = i*head->width;
     281           0 :             for ( j=0; j<head->width; ++j ) {
     282           0 :                 int b = getc(file);
     283           0 :                 int g = getc(file);
     284           0 :                 int r = getc(file);
     285           0 :                 head->int32_pixels[ii+j] = COLOR_CREATE(r,g,b);
     286             :             }
     287           0 :             for ( j=0; j<excess; ++j )
     288           0 :                 (void) getc(file);      /* ignore padding */
     289             :         }
     290           0 :     } else if ( head->bitsperpixel==32 && head->compression==0 ) {
     291           0 :         for ( i=0; i<head->height; ++i ) {
     292           0 :             ii = i*head->width;
     293           0 :             for ( j=0; j<head->width; ++j ) {
     294             :                 int b,g,r;
     295           0 :                 b = getc(file);
     296           0 :                 g = getc(file);
     297           0 :                 r = getc(file);
     298           0 :                 (void) getc(file);      /* Ignore the alpha channel */
     299           0 :                 head->int32_pixels[ii+j] = COLOR_CREATE(r,g,b);
     300             :             }
     301             :         }
     302           0 :     } else if ( head->bitsperpixel==16 ) {
     303           0 :         for ( i=0; i<head->height; ++i ) {
     304           0 :             ii = i*head->width;
     305           0 :             for ( j=0; j<head->width; ++j ) {
     306           0 :                 int pix = getshort(file);
     307           0 :                 head->int32_pixels[ii+j] = COLOR_CREATE((pix&head->red_mask)>>head->red_shift,
     308             :                         (pix&head->green_mask)>>head->green_shift,
     309             :                         (pix&head->blue_mask)>>head->blue_shift);
     310             :             }
     311             :         }
     312           0 :         if ( head->width&1 )
     313           0 :             getshort(file);
     314           0 :     } else if ( head->bitsperpixel==32 ) {
     315           0 :         for ( i=0; i<head->height; ++i ) {
     316           0 :             ii = i*head->width;
     317           0 :             for ( j=0; j<head->width; ++j ) {
     318             :                 long pix;
     319           0 :                 if ( getlong(file,&pix) )
     320           0 :                     return( 1 );
     321           0 :                 head->int32_pixels[ii+j] = COLOR_CREATE((pix&head->red_mask)>>head->red_shift,
     322             :                         (pix&head->green_mask)>>head->green_shift,
     323             :                         (pix&head->blue_mask)>>head->blue_shift);
     324             :             }
     325             :         }
     326             :     }
     327             : 
     328           0 :     if ( feof(file )) {         /* Did we get an incomplete file? */
     329           0 :         return( 0 );
     330             :     }
     331             : 
     332           0 : return( 1 );
     333             : }
     334             : 
     335           0 : GImage *GImageRead_Bmp(FILE *file) {
     336             : /* Import a BMP image (based on file handle), cleanup & return NULL if error */
     337             :     struct bmpheader bmp;
     338             :     int i,l;
     339           0 :     GImage *ret = NULL;
     340             :     struct _GImage *base;
     341             : 
     342           0 :     if ( file==NULL )
     343           0 :         return( NULL );
     344             : 
     345             :     /* First, read-in header information */
     346           0 :     memset(&bmp,'\0',sizeof(bmp));
     347           0 :     if ( fillbmpheader(file,&bmp) )
     348           0 :         goto errorGImageReadBmp;
     349             : 
     350             :     /* Create memory-space to read-in bmp file */
     351           0 :     if ( (bmp.bitsperpixel>=16 && \
     352           0 :          (bmp.int32_pixels=(uint32 *)(malloc(bmp.height*bmp.width*sizeof(uint32))))==NULL) || \
     353           0 :          (bmp.bitsperpixel==1  && \
     354           0 :          (bmp.byte_pixels=(unsigned char *)(malloc(bmp.height*((bmp.width+7)/8)*sizeof(unsigned char))))==NULL) || \
     355           0 :          (bmp.byte_pixels=(unsigned char *)(malloc(bmp.height*bmp.width*sizeof(unsigned char))))==NULL ) {
     356           0 :         NoMoreMemMessage();
     357           0 :         return( NULL );
     358             :     }
     359             : 
     360           0 :     if ( !readpixels(file,&bmp) )
     361           0 :         goto errorGImageReadBmp;
     362             : 
     363           0 :     if ( !bmp.invert ) {
     364           0 :         if ( (ret=_GImage_Create(bmp.bitsperpixel>=16?it_true:bmp.bitsperpixel!=1?it_index:it_mono,
     365           0 :                 bmp.width, bmp.height))==NULL ) {
     366           0 :             NoMoreMemMessage();
     367           0 :             goto errorGImageMemBmp;
     368             :         }
     369           0 :         if ( bmp.bitsperpixel>=16 ) {
     370           0 :             ret->u.image->data = (uint8 *) bmp.int32_pixels;
     371           0 :         } else if ( bmp.bitsperpixel!=1 ) {
     372           0 :             ret->u.image->data = (uint8 *) bmp.byte_pixels;
     373             :         }
     374             :     } else {
     375           0 :         if ( bmp.bitsperpixel>=16 ) {
     376           0 :             if ( (ret=GImageCreate(it_true,bmp.width, bmp.height))==NULL ) {
     377           0 :                 NoMoreMemMessage();
     378           0 :                 goto errorGImageMemBmp;
     379             :             }
     380           0 :             base = ret->u.image;
     381           0 :             for ( i=0; i<bmp.height; ++i ) {
     382           0 :                 l = bmp.height-1-i;
     383           0 :                 memcpy(base->data+l*base->bytes_per_line,bmp.int32_pixels+i*bmp.width,bmp.width*sizeof(uint32));
     384             :             }
     385           0 :             free(bmp.int32_pixels);
     386           0 :         } else if ( bmp.bitsperpixel!=1 ) {
     387           0 :             if ( (ret=GImageCreate(it_index,bmp.width, bmp.height))==NULL ) {
     388           0 :                 NoMoreMemMessage();
     389           0 :                 goto errorGImageMemBmp;
     390             :             }
     391           0 :             base = ret->u.image;
     392           0 :             for ( i=0; i<bmp.height; ++i ) {
     393           0 :                 l = bmp.height-1-i;
     394           0 :                 memcpy(base->data+l*base->bytes_per_line,bmp.byte_pixels+i*bmp.width,bmp.width);
     395             :             }
     396           0 :             free(bmp.byte_pixels);
     397             :         } else {
     398           0 :             if ( (ret=GImageCreate(it_mono,bmp.width, bmp.height))==NULL ) {
     399           0 :                 NoMoreMemMessage();
     400           0 :                 goto errorGImageMemBmp;
     401             :             }
     402           0 :             base = ret->u.image;
     403           0 :             for ( i=0; i<bmp.height; ++i ) {
     404           0 :                 l = bmp.height-1-i;
     405           0 :                 memcpy(base->data+l*base->bytes_per_line,bmp.byte_pixels+i*base->bytes_per_line,base->bytes_per_line);
     406             :             }
     407           0 :             free(bmp.byte_pixels);
     408             :         }
     409             :     }
     410           0 :     if ( ret->u.image->image_type==it_index ) {
     411           0 :         ret->u.image->clut->clut_len = bmp.colorsused;
     412           0 :         memcpy(ret->u.image->clut->clut,bmp.clut,bmp.colorsused*sizeof(Color));
     413           0 :         ret->u.image->clut->trans_index = COLOR_UNKNOWN;
     414           0 :     } else if ( ret->u.image->image_type==it_mono && bmp.colorsused!=0 ) {
     415           0 :         if ( (ret->u.image->clut=(GClut *)(calloc(1,sizeof(GClut))))==NULL ) {
     416           0 :             NoMoreMemMessage();
     417           0 :             goto errorGImageMemBmp;
     418             :         }
     419           0 :         ret->u.image->clut->clut_len = bmp.colorsused;
     420           0 :         memcpy(ret->u.image->clut->clut,bmp.clut,bmp.colorsused*sizeof(Color));
     421           0 :         ret->u.image->clut->trans_index = COLOR_UNKNOWN;
     422             :     }
     423           0 :     return( ret );
     424             : 
     425             : errorGImageReadBmp:
     426           0 :     fprintf(stderr,"Bad input file\n");
     427             : errorGImageMemBmp:
     428           0 :     GImageDestroy(ret);
     429           0 :     if ( bmp.bitsperpixel>=16 ) free(bmp.int32_pixels);
     430           0 :     else free(bmp.byte_pixels);
     431           0 :     return( NULL );
     432             : }
     433             : 
     434           0 : GImage *GImageReadBmp(char *filename) {
     435             : /* Import a BMP image, else cleanup and return NULL if error found */
     436             :     FILE *file;                 /* source file */
     437             :     GImage *ret;
     438             : 
     439           0 :     if ( (file=fopen(filename,"rb"))==NULL ) {
     440           0 :         fprintf(stderr,"Can't open \"%s\"\n", filename);
     441           0 :         return( NULL );
     442             :     }
     443             : 
     444           0 :     ret = GImageRead_Bmp(file);
     445           0 :     fclose(file);
     446           0 :     return( ret );
     447             : }

Generated by: LCOV version 1.10