lib/DtHelp/il: remove register keyword
[oweals/cde.git] / cde / lib / DtHelp / il / ilutiljpeg.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: ilutiljpeg.c /main/3 1995/10/23 16:02:31 rswiston $ */
24 /**---------------------------------------------------------------------
25 ***     
26 ***    (c)Copyright 1991 Hewlett-Packard Co.
27 ***    
28 ***                             RESTRICTED RIGHTS LEGEND
29 ***    Use, duplication, or disclosure by the U.S. Government is subject to
30 ***    restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
31 ***    Technical Data and Computer Software clause in DFARS 252.227-7013.
32 ***                             Hewlett-Packard Company
33 ***                             3000 Hanover Street
34 ***                             Palo Alto, CA 94304 U.S.A.
35 ***    Rights for non-DOD U.S. Government Departments and Agencies are as set
36 ***    forth in FAR 52.227-19(c)(1,2).
37 ***
38 ***-------------------------------------------------------------------*/
39
40 #include <stdlib.h>
41
42 #include "ilint.h"
43 #include "ilerrors.h"
44 #include "iljpgdecode.h"
45 #include "iljpgencode.h"
46 #include "ilutiljpeg.h"
47
48
49     /*  -------------------- _ilJPEGDataIn -------------------------- */
50     /*  Copy general data (but *not* table info) from IL data into 
51         IL JPG package format.
52     */
53 IL_PRIVATE void _ilJPEGDataIn (
54     const ilImageDes    *pDes,
55     long                          width,
56     long                          height,
57     iljpgDataPtr         pDst
58     )
59 {
60     int                     maxSubsample;
61
62     pDst->width = width;
63     pDst->height = height;
64     pDst->nComps = pDes->nSamplesPerPixel;
65
66         /*  Set IL subsample info into iljpg Hori/VertFactor info, which is essentially
67             the inverse of IL subsample data: for each sample/comp, hori/vert:
68                 iljpgFactor[comp] = maxILSubsample/ILSubsample[comp]
69             NOTE: currently only YCbCr data in IL is subsampled!
70         */
71     if (pDes->type == IL_YCBCR) {
72         const ilYCbCrSampleInfo *pSample = pDes->typeInfo.YCbCr.sample;
73
74         maxSubsample = pSample[0].subsampleHoriz;
75         if (pSample[1].subsampleHoriz > maxSubsample)
76             maxSubsample = pSample[1].subsampleHoriz;
77         if (pSample[2].subsampleHoriz > maxSubsample)
78             maxSubsample = pSample[2].subsampleHoriz;
79         pDst->maxHoriFactor = maxSubsample;
80         pDst->comp[0].horiFactor = maxSubsample / pSample[0].subsampleHoriz;
81         pDst->comp[1].horiFactor = maxSubsample / pSample[1].subsampleHoriz;
82         pDst->comp[2].horiFactor = maxSubsample / pSample[2].subsampleHoriz;
83
84         maxSubsample = pSample[0].subsampleVert;
85         if (pSample[1].subsampleVert > maxSubsample)
86             maxSubsample = pSample[1].subsampleVert;
87         if (pSample[2].subsampleVert > maxSubsample)
88             maxSubsample = pSample[2].subsampleVert;
89         pDst->maxVertFactor = maxSubsample;
90         pDst->comp[0].vertFactor = maxSubsample / pSample[0].subsampleVert;
91         pDst->comp[1].vertFactor = maxSubsample / pSample[1].subsampleVert;
92         pDst->comp[2].vertFactor = maxSubsample / pSample[2].subsampleVert;
93         }
94     else {
95         pDst->maxHoriFactor = 1;
96         pDst->maxVertFactor = 1;
97         pDst->comp[0].horiFactor = 1;
98         pDst->comp[0].vertFactor = 1;
99         pDst->comp[1].horiFactor = 1;
100         pDst->comp[1].vertFactor = 1;
101         pDst->comp[2].horiFactor = 1;
102         pDst->comp[2].vertFactor = 1;
103         pDst->comp[3].horiFactor = 1;
104         pDst->comp[3].vertFactor = 1;
105         }
106 }
107
108     /*  -------------------- _ilJPEGTablesIn -------------------------- */
109     /*  Copy table info from IL format into IL JPG package format.
110         Note: the restartInterval is also copied.
111     */
112 IL_PRIVATE void _ilJPEGTablesIn (
113     ilJPEGData    *pSrc,
114     iljpgDataPtr   pDst
115     )
116 {
117
118         /*  Copy the restartInterval; just convenient to do so in this function */
119     pDst->restartInterval = pSrc->restartInterval;
120
121         /*  Tables are independent of samples; copy all 4 */
122     pDst->QTables[0] = pSrc->QTables[0];
123     pDst->QTables[1] = pSrc->QTables[1];
124     pDst->QTables[2] = pSrc->QTables[2];
125     pDst->QTables[3] = pSrc->QTables[3];
126
127     pDst->DCTables[0] = pSrc->DCTables[0];
128     pDst->DCTables[1] = pSrc->DCTables[1];
129     pDst->DCTables[2] = pSrc->DCTables[2];
130     pDst->DCTables[3] = pSrc->DCTables[3];
131
132     pDst->ACTables[0] = pSrc->ACTables[0];
133     pDst->ACTables[1] = pSrc->ACTables[1];
134     pDst->ACTables[2] = pSrc->ACTables[2];
135     pDst->ACTables[3] = pSrc->ACTables[3];
136
137         /*  Copy 4 samples / components of indices into above tables */
138     pDst->comp[0].QTableIndex = pSrc->sample[0].QTableIndex;
139     pDst->comp[0].DCTableIndex = pSrc->sample[0].DCTableIndex;
140     pDst->comp[0].ACTableIndex = pSrc->sample[0].ACTableIndex;
141
142     pDst->comp[1].QTableIndex = pSrc->sample[1].QTableIndex;
143     pDst->comp[1].DCTableIndex = pSrc->sample[1].DCTableIndex;
144     pDst->comp[1].ACTableIndex = pSrc->sample[1].ACTableIndex;
145
146     pDst->comp[2].QTableIndex = pSrc->sample[2].QTableIndex;
147     pDst->comp[2].DCTableIndex = pSrc->sample[2].DCTableIndex;
148     pDst->comp[2].ACTableIndex = pSrc->sample[2].ACTableIndex;
149
150     pDst->comp[3].QTableIndex = pSrc->sample[3].QTableIndex;
151     pDst->comp[3].DCTableIndex = pSrc->sample[3].DCTableIndex;
152     pDst->comp[3].ACTableIndex = pSrc->sample[3].ACTableIndex;
153 }
154
155
156     /*  -------------------- _ilJPEGFreeTables -------------------------- */
157     /*  Free the tables in the given IL JPEG data block, which is not freed.
158     */
159 IL_PRIVATE void _ilJPEGFreeTables (
160     ilJPEGData    *pData
161     )
162 {
163     int            i;
164
165     for (i = 0; i < 4; i++) {
166         if (pData->QTables[i]) {
167             IL_FREE (pData->QTables[i]);
168             pData->QTables[i] = (ilPtr)NULL;
169             }
170         if (pData->DCTables[i]) {
171             IL_FREE (pData->DCTables[i]);
172             pData->DCTables[i] = (ilPtr)NULL;
173             }
174         if (pData->ACTables[i]) {
175             IL_FREE (pData->ACTables[i]);
176             pData->ACTables[i] = (ilPtr)NULL;
177             }
178         }
179 }
180
181
182     /*  -------------------- _ilJPEGCopyHuffmanTable -------------------------- */
183     /*  Copy the given JPEG Huffman table into a malloc'd space and return a ptr
184         to it or null if malloc failed.
185     */
186 static ilPtr _ilJPEGCopyHuffmanTable (
187     ilPtr          pSrc
188     )
189 {
190     int            i, nBytes;
191     ilPtr          pDst;
192
193         /*  Huffman tables are: 16 bytes of # occurrences each # bits, followed by
194             bytes for each of those # occurrences.  Size of table = 16 + sum(0..15).
195         */
196     for (i = 0, nBytes = 16; i < 16; i++)
197         nBytes += pSrc[i];
198     if (!(pDst = (ilPtr)IL_MALLOC (nBytes)))
199         return (ilPtr)NULL;
200     bcopy ((char *)pSrc, (char *)pDst, nBytes);
201     return pDst;
202 }
203
204
205     /*  -------------------- _ilJPEGCopyData -------------------------- */
206     /*  Copy data from pSrc to pDst, mallocing and copying contents of tables.
207         If an error, free all malloc'd tables in dest, null them and return false.
208     */
209 IL_PRIVATE ilBool _ilJPEGCopyData (
210     ilJPEGData    *pSrc,
211     ilJPEGData    *pDst
212     )
213 {
214     int            i;
215
216         /*  Zero table ptrs in *pDst in case of error; copy index info */
217     bzero ((char *)pDst, sizeof (ilJPEGData));
218     for (i = 0; i < IL_MAX_SAMPLES; i++)
219         pDst->sample[i] = pSrc->sample[i];
220
221         /*  For each non-null table in *pSrc, malloc space, copy contents, set pDst */
222     for (i = 0; i < 4; i++) {
223         if (pSrc->QTables[i]) {
224             if (!(pDst->QTables[i] = (ilPtr)IL_MALLOC (64)))
225                 goto cdMallocError;
226             bcopy ((char *)pSrc->QTables[i], (char *)pDst->QTables[i], 64);
227             }
228         if (pSrc->DCTables[i])
229             if (!(pDst->DCTables[i] = _ilJPEGCopyHuffmanTable (pSrc->DCTables[i])))
230                 goto cdMallocError;
231         if (pSrc->ACTables[i])
232             if (!(pDst->ACTables[i] = _ilJPEGCopyHuffmanTable (pSrc->ACTables[i])))
233                 goto cdMallocError;
234         }
235
236         /*  Copy restart interval */
237     pDst->restartInterval = pSrc->restartInterval;
238
239     return TRUE;
240
241         /*  Goto point on malloc error: free all tables in pDst, return false */
242 cdMallocError:
243     _ilJPEGFreeTables (pDst);
244     return FALSE;
245 }
246
247
248     /*  -------------------- _ilReallocJPEGEncode -------------------------- */
249     /*  Called by ILJPG_ENCODE_PUT_BYTE() macro to reallocate the buffer 
250         defined by "pStream" so that there is space for *exactly* "nBytes" bytes
251         to be written.  Zero (0) is returned if success else an error code.
252     */
253 IL_PRIVATE iljpgError _ilReallocJPEGEncode (
254     ilJPEGEncodeStreamPtr pStream,
255     long                    nBytes
256     )
257 {
258     long           offset;
259
260         /*  Allocate space so exactly "nBytes" more bytes will fit in output buffer.
261             There are "offset" bytes in the buffer now so allocate offset + nBytes.
262         */
263     if (pStream->pBuffer) {
264         offset = pStream->pDst - pStream->pBuffer;
265         pStream->pBuffer = (ilPtr)IL_REALLOC (pStream->pBuffer, offset + nBytes);
266         }
267     else {
268         offset = 0;                         /* no buffer yet; allocate one */
269         pStream->pBuffer = (ilPtr)IL_MALLOC (offset + nBytes);
270         }
271     if (!pStream->pBuffer) {
272         pStream->pDst = pStream->pPastEndBuffer = (ilPtr)NULL;
273         return ILJPG_ERROR_ENCODE_MALLOC;
274         }
275
276         /*  Successful realloc: set end of buffer to pBuffer + new size; set pDst
277             to pBuffer + offset and return success.
278         */
279     pStream->pPastEndBuffer = pStream->pBuffer + offset + nBytes;
280     pStream->pDst = pStream->pBuffer + offset;
281
282     return 0;
283 }
284
285