LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_next.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 52 71 73.2 %
Date: 2024-05-03 15:49:35 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1988-1997 Sam Leffler
       3             :  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
       4             :  *
       5             :  * Permission to use, copy, modify, distribute, and sell this software and
       6             :  * its documentation for any purpose is hereby granted without fee, provided
       7             :  * that (i) the above copyright notices and this permission notice appear in
       8             :  * all copies of the software and related documentation, and (ii) the names of
       9             :  * Sam Leffler and Silicon Graphics may not be used in any advertising or
      10             :  * publicity relating to the software without the specific, prior written
      11             :  * permission of Sam Leffler and Silicon Graphics.
      12             :  *
      13             :  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
      14             :  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
      15             :  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
      16             :  *
      17             :  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
      18             :  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
      19             :  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
      20             :  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
      21             :  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      22             :  * OF THIS SOFTWARE.
      23             :  */
      24             : 
      25             : #include "tiffiop.h"
      26             : #ifdef NEXT_SUPPORT
      27             : /*
      28             :  * TIFF Library.
      29             :  *
      30             :  * NeXT 2-bit Grey Scale Compression Algorithm Support
      31             :  */
      32             : 
      33             : #define SETPIXEL(op, v)                                                        \
      34             :     {                                                                          \
      35             :         switch (npixels++ & 3)                                                 \
      36             :         {                                                                      \
      37             :             case 0:                                                            \
      38             :                 op[0] = (unsigned char)((v) << 6);                             \
      39             :                 break;                                                         \
      40             :             case 1:                                                            \
      41             :                 op[0] |= (v) << 4;                                             \
      42             :                 break;                                                         \
      43             :             case 2:                                                            \
      44             :                 op[0] |= (v) << 2;                                             \
      45             :                 break;                                                         \
      46             :             case 3:                                                            \
      47             :                 *op++ |= (v);                                                  \
      48             :                 op_offset++;                                                   \
      49             :                 break;                                                         \
      50             :         }                                                                      \
      51             :     }
      52             : 
      53             : #define LITERALROW 0x00
      54             : #define LITERALSPAN 0x40
      55             : #define WHITE ((1 << 2) - 1)
      56             : 
      57           3 : static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
      58             : {
      59             :     static const char module[] = "NeXTDecode";
      60             :     unsigned char *bp, *op;
      61             :     tmsize_t cc;
      62             :     uint8_t *row;
      63             :     tmsize_t scanline, n;
      64             : 
      65             :     (void)s;
      66             :     /*
      67             :      * Each scanline is assumed to start off as all
      68             :      * white (we assume a PhotometricInterpretation
      69             :      * of ``min-is-black'').
      70             :      */
      71           6 :     for (op = (unsigned char *)buf, cc = occ; cc-- > 0;)
      72           3 :         *op++ = 0xff;
      73             : 
      74           3 :     bp = (unsigned char *)tif->tif_rawcp;
      75           3 :     cc = tif->tif_rawcc;
      76           3 :     scanline = tif->tif_scanlinesize;
      77           3 :     if (occ % scanline)
      78             :     {
      79           0 :         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
      80           0 :         return (0);
      81             :     }
      82           6 :     for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline)
      83             :     {
      84           3 :         n = *bp++;
      85           3 :         cc--;
      86           3 :         switch (n)
      87             :         {
      88           1 :             case LITERALROW:
      89             :                 /*
      90             :                  * The entire scanline is given as literal values.
      91             :                  */
      92           1 :                 if (cc < scanline)
      93           0 :                     goto bad;
      94           1 :                 _TIFFmemcpy(row, bp, scanline);
      95           1 :                 bp += scanline;
      96           1 :                 cc -= scanline;
      97           1 :                 break;
      98           1 :             case LITERALSPAN:
      99             :             {
     100             :                 tmsize_t off;
     101             :                 /*
     102             :                  * The scanline has a literal span that begins at some
     103             :                  * offset.
     104             :                  */
     105           1 :                 if (cc < 4)
     106           0 :                     goto bad;
     107           1 :                 off = (bp[0] * 256) + bp[1];
     108           1 :                 n = (bp[2] * 256) + bp[3];
     109           1 :                 if (cc < 4 + n || off + n > scanline)
     110           0 :                     goto bad;
     111           1 :                 _TIFFmemcpy(row + off, bp + 4, n);
     112           1 :                 bp += 4 + n;
     113           1 :                 cc -= 4 + n;
     114           1 :                 break;
     115             :             }
     116           1 :             default:
     117             :             {
     118           1 :                 uint32_t npixels = 0, grey;
     119           1 :                 tmsize_t op_offset = 0;
     120           1 :                 uint32_t imagewidth = tif->tif_dir.td_imagewidth;
     121           1 :                 if (isTiled(tif))
     122           0 :                     imagewidth = tif->tif_dir.td_tilewidth;
     123             : 
     124             :                 /*
     125             :                  * The scanline is composed of a sequence of constant
     126             :                  * color ``runs''.  We shift into ``run mode'' and
     127             :                  * interpret bytes as codes of the form
     128             :                  * <color><npixels> until we've filled the scanline.
     129             :                  */
     130           1 :                 op = row;
     131             :                 for (;;)
     132             :                 {
     133           1 :                     grey = (uint32_t)((n >> 6) & 0x3);
     134           1 :                     n &= 0x3f;
     135             :                     /*
     136             :                      * Ensure the run does not exceed the scanline
     137             :                      * bounds, potentially resulting in a security
     138             :                      * issue.
     139             :                      */
     140           6 :                     while (n-- > 0 && npixels < imagewidth &&
     141             :                            op_offset < scanline)
     142           5 :                         SETPIXEL(op, grey);
     143           1 :                     if (npixels >= imagewidth)
     144           1 :                         break;
     145           0 :                     if (op_offset >= scanline)
     146             :                     {
     147           0 :                         TIFFErrorExtR(tif, module,
     148             :                                       "Invalid data for scanline %" PRIu32,
     149             :                                       tif->tif_row);
     150           0 :                         return (0);
     151             :                     }
     152           0 :                     if (cc == 0)
     153           0 :                         goto bad;
     154           0 :                     n = *bp++;
     155           0 :                     cc--;
     156             :                 }
     157           1 :                 break;
     158             :             }
     159             :         }
     160             :     }
     161           3 :     tif->tif_rawcp = (uint8_t *)bp;
     162           3 :     tif->tif_rawcc = cc;
     163           3 :     return (1);
     164           0 : bad:
     165           0 :     TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
     166             :                   tif->tif_row);
     167           0 :     return (0);
     168             : }
     169             : 
     170           3 : static int NeXTPreDecode(TIFF *tif, uint16_t s)
     171             : {
     172             :     static const char module[] = "NeXTPreDecode";
     173           3 :     TIFFDirectory *td = &tif->tif_dir;
     174             :     (void)s;
     175             : 
     176           3 :     if (td->td_bitspersample != 2)
     177             :     {
     178           0 :         TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16,
     179           0 :                       td->td_bitspersample);
     180           0 :         return (0);
     181             :     }
     182           3 :     return (1);
     183             : }
     184             : 
     185           6 : int TIFFInitNeXT(TIFF *tif, int scheme)
     186             : {
     187             :     (void)scheme;
     188           6 :     tif->tif_predecode = NeXTPreDecode;
     189           6 :     tif->tif_decoderow = NeXTDecode;
     190           6 :     tif->tif_decodestrip = NeXTDecode;
     191           6 :     tif->tif_decodetile = NeXTDecode;
     192           6 :     return (1);
     193             : }
     194             : #endif /* NEXT_SUPPORT */

Generated by: LCOV version 1.14