~ubuntu-branches/ubuntu/quantal/tiff/quantal

« back to all changes in this revision

Viewing changes to libtiff/tif_next.c

  • Committer: Bazaar Package Importer
  • Author(s): Jay Berkenbilt
  • Date: 2009-08-28 15:44:23 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090828154423-7oisj77n302jrroa
Tags: 3.9.1-1
New upstream release

Show diffs side-by-side

added added

removed removed

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