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: 2026-02-21 16:21:44 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             :             default:                                                           \
      51             :                 break;                                                         \
      52             :         }                                                                      \
      53             :     }
      54             : 
      55             : #define LITERALROW 0x00
      56             : #define LITERALSPAN 0x40
      57             : #define WHITE ((1 << 2) - 1)
      58             : 
      59           3 : static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
      60             : {
      61             :     static const char module[] = "NeXTDecode";
      62             :     unsigned char *bp, *op;
      63             :     tmsize_t cc;
      64             :     uint8_t *row;
      65             :     tmsize_t scanline, n;
      66             : 
      67             :     (void)s;
      68             :     /*
      69             :      * Each scanline is assumed to start off as all
      70             :      * white (we assume a PhotometricInterpretation
      71             :      * of ``min-is-black'').
      72             :      */
      73           6 :     for (op = (unsigned char *)buf, cc = occ; cc-- > 0;)
      74           3 :         *op++ = 0xff;
      75             : 
      76           3 :     bp = (unsigned char *)tif->tif_rawcp;
      77           3 :     cc = tif->tif_rawcc;
      78           3 :     scanline = tif->tif_scanlinesize;
      79           3 :     if (occ % scanline)
      80             :     {
      81           0 :         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
      82           0 :         return (0);
      83             :     }
      84           6 :     for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline)
      85             :     {
      86           3 :         n = *bp++;
      87           3 :         cc--;
      88           3 :         switch (n)
      89             :         {
      90           1 :             case LITERALROW:
      91             :                 /*
      92             :                  * The entire scanline is given as literal values.
      93             :                  */
      94           1 :                 if (cc < scanline)
      95           0 :                     goto bad;
      96           1 :                 _TIFFmemcpy(row, bp, scanline);
      97           1 :                 bp += scanline;
      98           1 :                 cc -= scanline;
      99           1 :                 break;
     100           1 :             case LITERALSPAN:
     101             :             {
     102             :                 tmsize_t off;
     103             :                 /*
     104             :                  * The scanline has a literal span that begins at some
     105             :                  * offset.
     106             :                  */
     107           1 :                 if (cc < 4)
     108           0 :                     goto bad;
     109           1 :                 off = (bp[0] * 256) + bp[1];
     110           1 :                 n = (bp[2] * 256) + bp[3];
     111           1 :                 if (cc < 4 + n || off + n > scanline)
     112           0 :                     goto bad;
     113           1 :                 _TIFFmemcpy(row + off, bp + 4, n);
     114           1 :                 bp += 4 + n;
     115           1 :                 cc -= 4 + n;
     116           1 :                 break;
     117             :             }
     118           1 :             default:
     119             :             {
     120           1 :                 uint32_t npixels = 0, grey;
     121           1 :                 tmsize_t op_offset = 0;
     122           1 :                 uint32_t imagewidth = tif->tif_dir.td_imagewidth;
     123           1 :                 if (isTiled(tif))
     124           0 :                     imagewidth = tif->tif_dir.td_tilewidth;
     125             : 
     126             :                 /*
     127             :                  * The scanline is composed of a sequence of constant
     128             :                  * color ``runs''.  We shift into ``run mode'' and
     129             :                  * interpret bytes as codes of the form
     130             :                  * <color><npixels> until we've filled the scanline.
     131             :                  */
     132           1 :                 op = row;
     133             :                 for (;;)
     134             :                 {
     135           1 :                     grey = (uint32_t)((n >> 6) & 0x3);
     136           1 :                     n &= 0x3f;
     137             :                     /*
     138             :                      * Ensure the run does not exceed the scanline
     139             :                      * bounds, potentially resulting in a security
     140             :                      * issue.
     141             :                      */
     142           5 :                     while (n-- > 0 && npixels < imagewidth &&
     143             :                            op_offset < scanline)
     144           4 :                         SETPIXEL(op, grey);
     145           1 :                     if (npixels >= imagewidth)
     146           1 :                         break;
     147           0 :                     if (op_offset >= scanline)
     148             :                     {
     149           0 :                         TIFFErrorExtR(tif, module,
     150             :                                       "Invalid data for scanline %" PRIu32,
     151             :                                       tif->tif_row);
     152           0 :                         return (0);
     153             :                     }
     154           0 :                     if (cc == 0)
     155           0 :                         goto bad;
     156           0 :                     n = *bp++;
     157           0 :                     cc--;
     158             :                 }
     159           1 :                 break;
     160             :             }
     161             :         }
     162             :     }
     163           3 :     tif->tif_rawcp = (uint8_t *)bp;
     164           3 :     tif->tif_rawcc = cc;
     165           3 :     return (1);
     166           0 : bad:
     167           0 :     TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
     168             :                   tif->tif_row);
     169           0 :     return (0);
     170             : }
     171             : 
     172           3 : static int NeXTPreDecode(TIFF *tif, uint16_t s)
     173             : {
     174             :     static const char module[] = "NeXTPreDecode";
     175           3 :     TIFFDirectory *td = &tif->tif_dir;
     176             :     (void)s;
     177             : 
     178           3 :     if (td->td_bitspersample != 2)
     179             :     {
     180           0 :         TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16,
     181           0 :                       td->td_bitspersample);
     182           0 :         return (0);
     183             :     }
     184           3 :     return (1);
     185             : }
     186             : 
     187           6 : int TIFFInitNeXT(TIFF *tif, int scheme)
     188             : {
     189             :     (void)scheme;
     190           6 :     tif->tif_predecode = NeXTPreDecode;
     191           6 :     tif->tif_decoderow = NeXTDecode;
     192           6 :     tif->tif_decodestrip = NeXTDecode;
     193           6 :     tif->tif_decodetile = NeXTDecode;
     194           6 :     return (1);
     195             : }
     196             : #endif /* NEXT_SUPPORT */

Generated by: LCOV version 1.14