LCOV - code coverage report
Current view: directory - frmts/jpeg2000 - jpeg2000_vsil_io.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 95 74 77.9 %
Date: 2011-12-18 Functions: 9 9 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: jpeg2000_vsil_io.cpp 20996 2010-10-28 18:38:15Z rouault $
       3                 :  *
       4                 :  * Project:  JPEG-2000
       5                 :  * Purpose:  Return a stream for a VSIL file
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************/
       9                 : 
      10                 : /* Following code is mostly derived from jas_stream.c, which is licenced */
      11                 : /* under the below terms */
      12                 :  
      13                 : /*
      14                 :  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
      15                 :  *   British Columbia.
      16                 :  * Copyright (c) 2001-2003 Michael David Adams.
      17                 :  * All rights reserved.
      18                 :  */
      19                 : 
      20                 : /* __START_OF_JASPER_LICENSE__
      21                 :  * 
      22                 :  * JasPer License Version 2.0
      23                 :  * 
      24                 :  * Copyright (c) 2001-2006 Michael David Adams
      25                 :  * Copyright (c) 1999-2000 Image Power, Inc.
      26                 :  * Copyright (c) 1999-2000 The University of British Columbia
      27                 :  * 
      28                 :  * All rights reserved.
      29                 :  * 
      30                 :  * Permission is hereby granted, free of charge, to any person (the
      31                 :  * "User") obtaining a copy of this software and associated documentation
      32                 :  * files (the "Software"), to deal in the Software without restriction,
      33                 :  * including without limitation the rights to use, copy, modify, merge,
      34                 :  * publish, distribute, and/or sell copies of the Software, and to permit
      35                 :  * persons to whom the Software is furnished to do so, subject to the
      36                 :  * following conditions:
      37                 :  * 
      38                 :  * 1.  The above copyright notices and this permission notice (which
      39                 :  * includes the disclaimer below) shall be included in all copies or
      40                 :  * substantial portions of the Software.
      41                 :  * 
      42                 :  * 2.  The name of a copyright holder shall not be used to endorse or
      43                 :  * promote products derived from the Software without specific prior
      44                 :  * written permission.
      45                 :  * 
      46                 :  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
      47                 :  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
      48                 :  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
      49                 :  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
      50                 :  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      51                 :  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
      52                 :  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
      53                 :  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
      54                 :  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
      55                 :  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
      56                 :  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
      57                 :  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
      58                 :  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
      59                 :  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
      60                 :  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
      61                 :  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
      62                 :  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
      63                 :  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
      64                 :  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
      65                 :  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
      66                 :  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
      67                 :  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
      68                 :  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
      69                 :  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
      70                 :  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
      71                 :  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
      72                 :  * 
      73                 :  * __END_OF_JASPER_LICENSE__
      74                 :  */
      75                 : 
      76                 : #include "jpeg2000_vsil_io.h"
      77                 : #include "cpl_vsi.h"
      78                 : 
      79                 : CPL_CVSID("$Id: jpeg2000_vsil_io.cpp 20996 2010-10-28 18:38:15Z rouault $");
      80                 : 
      81                 : /*
      82                 :  * File descriptor file object.
      83                 :  */
      84                 : typedef struct {
      85                 :   VSILFILE* fp;
      86                 : } jas_stream_VSIFL_t;
      87                 : 
      88                 : /******************************************************************************\
      89                 : * File stream object.
      90                 : \******************************************************************************/
      91                 : 
      92            1730 : static int JPEG2000_VSIL_read(jas_stream_obj_t *obj, char *buf, int cnt)
      93                 : {
      94            1730 :   jas_stream_VSIFL_t *fileobj = JAS_CAST(jas_stream_VSIFL_t *, obj);
      95            1730 :   return VSIFReadL(buf, 1, cnt, fileobj->fp);
      96                 : }
      97                 : 
      98              11 : static int JPEG2000_VSIL_write(jas_stream_obj_t *obj, char *buf, int cnt)
      99                 : {
     100              11 :   jas_stream_VSIFL_t *fileobj = JAS_CAST(jas_stream_VSIFL_t *, obj);
     101              11 :   return VSIFWriteL(buf, 1, cnt, fileobj->fp);
     102                 : }
     103                 : 
     104              30 : static long JPEG2000_VSIL_seek(jas_stream_obj_t *obj, long offset, int origin)
     105                 : {
     106              30 :   jas_stream_VSIFL_t *fileobj = JAS_CAST(jas_stream_VSIFL_t *, obj);
     107              30 :     if (offset < 0 && origin == SEEK_CUR)
     108                 :     {
     109               0 :         origin = SEEK_SET;
     110               0 :         offset += VSIFTellL(fileobj->fp);
     111                 :     }
     112              30 :     else if (offset < 0 && origin == SEEK_END)
     113                 :     {
     114               0 :         origin = SEEK_SET;
     115               0 :         VSIFSeekL(fileobj->fp, 0, SEEK_END);
     116               0 :         offset += VSIFTellL(fileobj->fp);
     117                 :     }
     118              30 :   VSIFSeekL(fileobj->fp, offset, origin);
     119              30 :     return VSIFTellL(fileobj->fp);
     120                 : }
     121                 : 
     122              53 : static int JPEG2000_VSIL_close(jas_stream_obj_t *obj)
     123                 : {
     124              53 :   jas_stream_VSIFL_t *fileobj = JAS_CAST(jas_stream_VSIFL_t *, obj);
     125              53 :     VSIFCloseL(fileobj->fp);
     126              53 :     fileobj->fp = NULL;
     127              53 :   jas_free(fileobj);
     128              53 :   return 0;
     129                 : }
     130                 : 
     131                 : static jas_stream_ops_t JPEG2000_VSIL_stream_fileops = {
     132                 :   JPEG2000_VSIL_read,
     133                 :   JPEG2000_VSIL_write,
     134                 :   JPEG2000_VSIL_seek,
     135                 :   JPEG2000_VSIL_close
     136                 : };
     137                 : 
     138                 : /******************************************************************************\
     139                 : * Code for opening and closing streams.
     140                 : \******************************************************************************/
     141                 : 
     142              55 : static jas_stream_t *JPEG2000_VSIL_jas_stream_create()
     143                 : {
     144                 :   jas_stream_t *stream;
     145                 : 
     146              55 :   if (!(stream = (jas_stream_t*) jas_malloc(sizeof(jas_stream_t)))) {
     147               0 :     return 0;
     148                 :   }
     149              55 :   stream->openmode_ = 0;
     150              55 :   stream->bufmode_ = 0;
     151              55 :   stream->flags_ = 0;
     152              55 :   stream->bufbase_ = 0;
     153              55 :   stream->bufstart_ = 0;
     154              55 :   stream->bufsize_ = 0;
     155              55 :   stream->ptr_ = 0;
     156              55 :   stream->cnt_ = 0;
     157              55 :   stream->ops_ = 0;
     158              55 :   stream->obj_ = 0;
     159              55 :   stream->rwcnt_ = 0;
     160              55 :   stream->rwlimit_ = -1;
     161                 : 
     162              55 :   return stream;
     163                 : }
     164                 : 
     165               2 : static void JPEG2000_VSIL_jas_stream_destroy(jas_stream_t *stream)
     166                 : {
     167                 :   /* If the memory for the buffer was allocated with malloc, free
     168                 :   this memory. */
     169               2 :   if ((stream->bufmode_ & JAS_STREAM_FREEBUF) && stream->bufbase_) {
     170               0 :     jas_free(stream->bufbase_);
     171               0 :     stream->bufbase_ = 0;
     172                 :   }
     173               2 :   jas_free(stream);
     174               2 : }
     175                 : 
     176                 : 
     177                 : /******************************************************************************\
     178                 : * Buffer initialization code.
     179                 : \******************************************************************************/
     180                 : 
     181              53 : static void JPEG2000_VSIL_jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
     182                 :   int bufsize)
     183                 : {
     184                 :   /* If this function is being called, the buffer should not have been
     185                 :     initialized yet. */
     186              53 :   assert(!stream->bufbase_);
     187                 : 
     188              53 :   if (bufmode != JAS_STREAM_UNBUF) {
     189                 :     /* The full- or line-buffered mode is being employed. */
     190              53 :     if (!buf) {
     191                 :       /* The caller has not specified a buffer to employ, so allocate
     192                 :         one. */
     193              53 :       if ((stream->bufbase_ = (unsigned char*)jas_malloc(JAS_STREAM_BUFSIZE +
     194                 :         JAS_STREAM_MAXPUTBACK))) {
     195              53 :         stream->bufmode_ |= JAS_STREAM_FREEBUF;
     196              53 :         stream->bufsize_ = JAS_STREAM_BUFSIZE;
     197                 :       } else {
     198                 :         /* The buffer allocation has failed.  Resort to unbuffered
     199                 :           operation. */
     200               0 :         stream->bufbase_ = stream->tinybuf_;
     201               0 :         stream->bufsize_ = 1;
     202                 :       }
     203                 :     } else {
     204                 :       /* The caller has specified a buffer to employ. */
     205                 :       /* The buffer must be large enough to accommodate maximum
     206                 :         putback. */
     207               0 :       assert(bufsize > JAS_STREAM_MAXPUTBACK);
     208               0 :       stream->bufbase_ = JAS_CAST(uchar *, buf);
     209               0 :       stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK;
     210                 :     }
     211                 :   } else {
     212                 :     /* The unbuffered mode is being employed. */
     213                 :     /* A buffer should not have been supplied by the caller. */
     214               0 :     assert(!buf);
     215                 :     /* Use a trivial one-character buffer. */
     216               0 :     stream->bufbase_ = stream->tinybuf_;
     217               0 :     stream->bufsize_ = 1;
     218                 :   }
     219              53 :   stream->bufstart_ = &stream->bufbase_[JAS_STREAM_MAXPUTBACK];
     220              53 :   stream->ptr_ = stream->bufstart_;
     221              53 :   stream->cnt_ = 0;
     222              53 :   stream->bufmode_ |= bufmode & JAS_STREAM_BUFMODEMASK;
     223              53 : }
     224                 : 
     225              55 : static int JPEG2000_VSIL_jas_strtoopenmode(const char *s)
     226                 : {
     227              55 :   int openmode = 0;
     228             231 :   while (*s != '\0') {
     229             121 :     switch (*s) {
     230                 :     case 'r':
     231              45 :       openmode |= JAS_STREAM_READ;
     232              45 :       break;
     233                 :     case 'w':
     234              10 :       openmode |= JAS_STREAM_WRITE | JAS_STREAM_CREATE;
     235              10 :       break;
     236                 :     case 'b':
     237              55 :       openmode |= JAS_STREAM_BINARY;
     238              55 :       break;
     239                 :     case 'a':
     240               0 :       openmode |= JAS_STREAM_APPEND;
     241               0 :       break;
     242                 :     case '+':
     243              11 :       openmode |= JAS_STREAM_READ | JAS_STREAM_WRITE;
     244                 :       break;
     245                 :     default:
     246                 :       break;
     247                 :     }
     248             121 :     ++s;
     249                 :   }
     250              55 :   return openmode;
     251                 : }
     252                 : 
     253              55 : jas_stream_t *JPEG2000_VSIL_fopen(const char *filename, const char *mode)
     254                 : {
     255                 :   jas_stream_t *stream;
     256                 :   jas_stream_VSIFL_t *obj;
     257                 : 
     258                 :   /* Allocate a stream object. */
     259              55 :   if (!(stream = JPEG2000_VSIL_jas_stream_create())) {
     260               0 :     return 0;
     261                 :   }
     262                 : 
     263                 :   /* Parse the mode string. */
     264              55 :   stream->openmode_ = JPEG2000_VSIL_jas_strtoopenmode(mode);
     265                 : 
     266                 :   /* Allocate space for the underlying file stream object. */
     267              55 :   if (!(obj = (jas_stream_VSIFL_t*) jas_malloc(sizeof(jas_stream_VSIFL_t)))) {
     268               0 :     JPEG2000_VSIL_jas_stream_destroy(stream);
     269               0 :     return 0;
     270                 :   }
     271              55 :   obj->fp = NULL;
     272              55 :   stream->obj_ = (void *) obj;
     273                 : 
     274                 :   /* Select the operations for a file stream object. */
     275              55 :   stream->ops_ = &JPEG2000_VSIL_stream_fileops;
     276                 : 
     277                 :   /* Open the underlying file. */
     278              55 :   if ((obj->fp = VSIFOpenL(filename, mode)) == NULL) {
     279               2 :     JPEG2000_VSIL_jas_stream_destroy(stream);
     280               2 :     return 0;
     281                 :   }
     282                 : 
     283                 :   /* By default, use full buffering for this type of stream. */
     284              53 :   JPEG2000_VSIL_jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);
     285                 : 
     286              53 :   return stream;
     287                 : }

Generated by: LCOV version 1.7