]>
Commit | Line | Data |
---|---|---|
14c7c974 A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights | |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.1 (the "License"). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the | |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License. | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | #ifndef lint | |
75b89a82 | 25 | static char rcsid[] = "$Header: /cvs/Darwin/boot/i386/util/tif_packbits.c,v 1.1.1.2 1999/08/04 21:17:19 wsanchez Exp $"; |
14c7c974 A |
26 | #endif |
27 | ||
28 | /* | |
29 | * Copyright (c) 1988, 1989, 1990, 1991 Sam Leffler | |
30 | * Copyright (c) 1991 Silicon Graphics, Inc. | |
31 | * | |
32 | * Permission to use, copy, modify, distribute, and sell this software and | |
33 | * its documentation for any purpose is hereby granted without fee, provided | |
34 | * that (i) the above copyright notices and this permission notice appear in | |
35 | * all copies of the software and related documentation, and (ii) the names of | |
36 | * Sam Leffler and Silicon Graphics may not be used in any advertising or | |
37 | * publicity relating to the software without the specific, prior written | |
38 | * permission of Sam Leffler and Silicon Graphics. | |
39 | * | |
40 | * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
41 | * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
42 | * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
43 | * | |
44 | * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | |
45 | * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
46 | * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
47 | * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
48 | * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
49 | * OF THIS SOFTWARE. | |
50 | */ | |
51 | ||
52 | /* | |
53 | * TIFF Library. | |
54 | * | |
55 | * PackBits Compression Algorithm Support | |
56 | */ | |
57 | #import "bitmap.h" | |
58 | ||
59 | typedef unsigned int u_int; | |
60 | typedef unsigned char u_char; | |
61 | ||
62 | static | |
63 | TIFFAppendToStrip(tif, strip, data, cc) | |
64 | TIFF *tif; | |
65 | u_int strip; | |
66 | u_char *data; | |
67 | u_int cc; | |
68 | { | |
69 | } | |
70 | ||
71 | ||
72 | ||
73 | /* | |
74 | * Encode a scanline of pixels. | |
75 | */ | |
76 | int | |
77 | PackBitsEncode(tif, bp, cc, s) | |
78 | TIFF *tif; | |
79 | u_char *bp; | |
80 | register int cc; | |
81 | u_int s; | |
82 | { | |
83 | register char *op, *lastliteral; | |
84 | register int n, b; | |
85 | enum { BASE, LITERAL, RUN, LITERAL_RUN } state; | |
86 | char *ep; | |
87 | int slop; | |
88 | ||
89 | op = tif->tif_rawcp; | |
90 | ep = tif->tif_rawdata + tif->tif_rawdatasize; | |
91 | state = BASE; | |
92 | lastliteral = 0; | |
93 | while (cc > 0) { | |
94 | /* | |
95 | * Find the longest string of identical bytes. | |
96 | */ | |
97 | b = *bp++, cc--, n = 1; | |
98 | for (; cc > 0 && b == *bp; cc--, bp++) | |
99 | n++; | |
100 | again: | |
101 | if (op + 2 >= ep) { /* insure space for new data */ | |
102 | /* | |
103 | * Be careful about writing the last | |
104 | * literal. Must write up to that point | |
105 | * and then copy the remainder to the | |
106 | * front of the buffer. | |
107 | */ | |
108 | if (state == LITERAL || state == LITERAL_RUN) { | |
109 | slop = op - lastliteral; | |
110 | tif->tif_rawcc += lastliteral - tif->tif_rawcp; | |
111 | // no space left | |
112 | return (-1); | |
113 | op = tif->tif_rawcp; | |
114 | for (; slop-- > 0; *op++ = *lastliteral++) | |
115 | ; | |
116 | lastliteral = tif->tif_rawcp; | |
117 | } else { | |
118 | tif->tif_rawcc += op - tif->tif_rawcp; | |
119 | // no space left | |
120 | return (-1); | |
121 | op = tif->tif_rawcp; | |
122 | } | |
123 | } | |
124 | switch (state) { | |
125 | case BASE: /* initial state, set run/literal */ | |
126 | if (n > 1) { | |
127 | state = RUN; | |
128 | if (n > 128) { | |
129 | *op++ = -127; | |
130 | *op++ = b; | |
131 | n -= 128; | |
132 | goto again; | |
133 | } | |
134 | *op++ = -(n-1); | |
135 | *op++ = b; | |
136 | } else { | |
137 | lastliteral = op; | |
138 | *op++ = 0; | |
139 | *op++ = b; | |
140 | state = LITERAL; | |
141 | } | |
142 | break; | |
143 | case LITERAL: /* last object was literal string */ | |
144 | if (n > 1) { | |
145 | state = LITERAL_RUN; | |
146 | if (n > 128) { | |
147 | *op++ = -127; | |
148 | *op++ = b; | |
149 | n -= 128; | |
150 | goto again; | |
151 | } | |
152 | *op++ = -(n-1); /* encode run */ | |
153 | *op++ = b; | |
154 | } else { /* extend literal */ | |
155 | if (++(*lastliteral) == 127) | |
156 | state = BASE; | |
157 | *op++ = b; | |
158 | } | |
159 | break; | |
160 | case RUN: /* last object was run */ | |
161 | if (n > 1) { | |
162 | if (n > 128) { | |
163 | *op++ = -127; | |
164 | *op++ = b; | |
165 | n -= 128; | |
166 | goto again; | |
167 | } | |
168 | *op++ = -(n-1); | |
169 | *op++ = b; | |
170 | } else { | |
171 | lastliteral = op; | |
172 | *op++ = 0; | |
173 | *op++ = b; | |
174 | state = LITERAL; | |
175 | } | |
176 | break; | |
177 | case LITERAL_RUN: /* literal followed by a run */ | |
178 | /* | |
179 | * Check to see if previous run should | |
180 | * be converted to a literal, in which | |
181 | * case we convert literal-run-literal | |
182 | * to a single literal. | |
183 | */ | |
184 | if (n == 1 && op[-2] == (char)-1 && | |
185 | *lastliteral < 126) { | |
186 | state = (((*lastliteral) += 2) == 127 ? | |
187 | BASE : LITERAL); | |
188 | op[-2] = op[-1]; /* replicate */ | |
189 | } else | |
190 | state = RUN; | |
191 | goto again; | |
192 | } | |
193 | } | |
194 | tif->tif_rawcc += op - tif->tif_rawcp; | |
195 | tif->tif_rawcp = op; | |
196 | return (1); | |
197 | } | |
198 |