2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: ilutiljpeg.c /main/3 1995/10/23 16:02:31 rswiston $ */
24 /**---------------------------------------------------------------------
26 *** (c)Copyright 1991 Hewlett-Packard Co.
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).
38 ***-------------------------------------------------------------------*/
44 #include "iljpgdecode.h"
45 #include "iljpgencode.h"
46 #include "ilutiljpeg.h"
49 /* -------------------- _ilJPEGDataIn -------------------------- */
50 /* Copy general data (but *not* table info) from IL data into
51 IL JPG package format.
53 IL_PRIVATE void _ilJPEGDataIn (
54 const ilImageDes *pDes,
63 pDst->height = height;
64 pDst->nComps = pDes->nSamplesPerPixel;
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!
71 if (pDes->type == IL_YCBCR) {
72 const ilYCbCrSampleInfo *pSample = pDes->typeInfo.YCbCr.sample;
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;
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;
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;
108 /* -------------------- _ilJPEGTablesIn -------------------------- */
109 /* Copy table info from IL format into IL JPG package format.
110 Note: the restartInterval is also copied.
112 IL_PRIVATE void _ilJPEGTablesIn (
118 /* Copy the restartInterval; just convenient to do so in this function */
119 pDst->restartInterval = pSrc->restartInterval;
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];
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];
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];
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;
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;
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;
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;
156 /* -------------------- _ilJPEGFreeTables -------------------------- */
157 /* Free the tables in the given IL JPEG data block, which is not freed.
159 IL_PRIVATE void _ilJPEGFreeTables (
165 for (i = 0; i < 4; i++) {
166 if (pData->QTables[i]) {
167 IL_FREE (pData->QTables[i]);
168 pData->QTables[i] = (ilPtr)NULL;
170 if (pData->DCTables[i]) {
171 IL_FREE (pData->DCTables[i]);
172 pData->DCTables[i] = (ilPtr)NULL;
174 if (pData->ACTables[i]) {
175 IL_FREE (pData->ACTables[i]);
176 pData->ACTables[i] = (ilPtr)NULL;
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.
186 static ilPtr _ilJPEGCopyHuffmanTable (
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).
196 for (i = 0, nBytes = 16; i < 16; i++)
198 if (!(pDst = (ilPtr)IL_MALLOC (nBytes)))
200 bcopy ((char *)pSrc, (char *)pDst, nBytes);
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.
209 IL_PRIVATE ilBool _ilJPEGCopyData (
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];
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)))
226 bcopy ((char *)pSrc->QTables[i], (char *)pDst->QTables[i], 64);
228 if (pSrc->DCTables[i])
229 if (!(pDst->DCTables[i] = _ilJPEGCopyHuffmanTable (pSrc->DCTables[i])))
231 if (pSrc->ACTables[i])
232 if (!(pDst->ACTables[i] = _ilJPEGCopyHuffmanTable (pSrc->ACTables[i])))
236 /* Copy restart interval */
237 pDst->restartInterval = pSrc->restartInterval;
241 /* Goto point on malloc error: free all tables in pDst, return false */
243 _ilJPEGFreeTables (pDst);
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.
253 IL_PRIVATE iljpgError _ilReallocJPEGEncode (
254 ilJPEGEncodeStreamPtr pStream,
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.
263 if (pStream->pBuffer) {
264 offset = pStream->pDst - pStream->pBuffer;
265 pStream->pBuffer = (ilPtr)IL_REALLOC (pStream->pBuffer, offset + nBytes);
268 offset = 0; /* no buffer yet; allocate one */
269 pStream->pBuffer = (ilPtr)IL_MALLOC (offset + nBytes);
271 if (!pStream->pBuffer) {
272 pStream->pDst = pStream->pPastEndBuffer = (ilPtr)NULL;
273 return ILJPG_ERROR_ENCODE_MALLOC;
276 /* Successful realloc: set end of buffer to pBuffer + new size; set pDst
277 to pBuffer + offset and return success.
279 pStream->pPastEndBuffer = pStream->pBuffer + offset + nBytes;
280 pStream->pDst = pStream->pBuffer + offset;