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

Generated by: LCOV version 1.14