123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: iljpgencode.c /main/3 1995/10/23 15:55:46 rswiston $ */
- /**---------------------------------------------------------------------
- ***
- *** (c)Copyright 1992 Hewlett-Packard Co.
- ***
- *** RESTRICTED RIGHTS LEGEND
- *** Use, duplication, or disclosure by the U.S. Government is subject to
- *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
- *** Technical Data and Computer Software clause in DFARS 252.227-7013.
- *** Hewlett-Packard Company
- *** 3000 Hanover Street
- *** Palo Alto, CA 94304 U.S.A.
- *** Rights for non-DOD U.S. Government Departments and Agencies are as set
- *** forth in FAR 52.227-19(c)(1,2).
- ***
- ***-------------------------------------------------------------------*/
- #include "iljpgencodeint.h"
- /* -------------------- iljpgEncodeInit -------------------------- */
- /* Init for JPEG encoding and return ptr to private block.
- */
- ILJPG_PUBLIC
- iljpgError iljpgEncodeInit (
- iljpgDataPtr pData,
- iljpgPtr *pPrivate /* RETURNED */
- )
- {
- iljpgEncodePrivPtr pPriv;
- iljpgECompPtr pComp;
- iljpgCompDataPtr pCompData;
- int comp;
- iljpgError error;
- unsigned int index, i;
- /* Validate *pData: valid hori/vertFactor, tables present, etc. */
- if (!_iljpgValidPars (pData))
- return ILJPG_ERROR_ENCODE_PARS;
- /* Allocate and return private block */
- pPriv = (iljpgEncodePrivPtr)ILJPG_MALLOC_ZERO (sizeof (iljpgEncodePrivRec));
- if (!pPriv)
- return ILJPG_ERROR_ENCODE_MALLOC;
- pPriv->pData = pData;
- *pPrivate = (iljpgPtr)pPriv;
- /* For DCT encoding, get and store into private a
- scaled version of each Q table.
- */
- for (i = 0; i < 4; i++)
- pPriv->DCTScaleTables[i] = (float *)NULL;
- for (i = 0; i < 4; i++) {
- if (pData->QTables[i]) {
- if (!(pPriv->DCTScaleTables[i] = (float *)ILJPG_MALLOC(sizeof(float) * 64)))
- return ILJPG_ERROR_ENCODE_MALLOC;
- if (error = _iljpgEnDCTScale (pData->QTables[i], pPriv->DCTScaleTables[i]))
- return error;
- }
- }
- /* Init Huffman encoding */
- if (error = _iljpgEnhuffInit (pPriv))
- return error;
- /* Setup static part of per-comp data; copy from other places */
- for (comp = 0, pCompData = pData->comp, pComp = pPriv->compData;
- comp < pData->nComps; comp++, pCompData++, pComp++) {
- pComp->pScale = pPriv->DCTScaleTables[pCompData->QTableIndex];
- pComp->horiFactor = pCompData->horiFactor;
- pComp->vertFactor = pCompData->vertFactor;
- pComp->width = pData->width * pCompData->horiFactor / pData->maxHoriFactor;
- pComp->mcuXInc = 8 * pCompData->horiFactor;
- pComp->mcuYInc = 8 * pCompData->vertFactor;
- }
- return 0;
- }
- /* -------------------- iljpgEncodeCleanup -------------------------- */
- /* Cleanup after JPEG encoding.
- */
- ILJPG_PUBLIC
- iljpgError iljpgEncodeCleanup (
- iljpgPtr pPrivate
- )
- {
- int i;
- iljpgEncodePrivPtr pPriv;
- iljpgError error;
- /* Free any scaled Q tables created by Init() */
- pPriv = (iljpgEncodePrivPtr)pPrivate;
- for (i = 0; i < 4; i++)
- if (pPriv->DCTScaleTables[i])
- ILJPG_FREE (pPriv->DCTScaleTables[i]);
- /* Cleanup Huffman */
- error = _iljpgEnhuffCleanup(pPriv);
- /* Free the given private data. Note that pPrivate->pData is not
- freed; that is done when the caller calls iljpgFreeData().
- */
- ILJPG_FREE (pPrivate);
- return error;
- }
- /* -------------------- iljpgEncodeExecute -------------------------- */
- /* Encode (compress) the pixels from the per-plane buffers pointed to
- by "pSrcPixels": one ptr per component (# of components = "nComps" in
- the iljpgData passed to iljpgEncodeInit()). "nSrcBytesPerRow" is length
- of each row in the corresponding buffers in "pSrcPixels".
- "pPrivate" is the ptr returned by iljpgEncodeInit().
- "nSrcLines" is the # of lines to read; encoding stops when nSrcLines
- lines have been encoded.
- */
- ILJPG_PUBLIC
- iljpgError iljpgEncodeExecute (
- iljpgPtr pPrivate,
- ILJPG_ENCODE_STREAM stream,
- long nSrcLines,
- iljpgPtr pSrcPixels[],
- long nSrcBytesPerRow[]
- )
- {
- iljpgEncodePrivPtr pPriv;
- iljpgDataPtr pData;
- iljpgECompPtr pComp;
- iljpgPtr pPixels;
- iljpgError error;
- long nBytesPerRow, mcuMaxX, mcuMaxY, bX, bY;
- int comp, v, h, mcuWidth, mcuHeight;
- int pixels[64];
- pPriv = (iljpgEncodePrivPtr)pPrivate;
- pData = pPriv->pData;
- /* Encode "interleaved" JPEG data, where all components are grouped together
- in Minimum Coded Unit (MCU) size, = 8 * max hori(width) or vert(height)
- factor. The "factors" are the inverse of IL subsample factors. For
- example, if component 0 is not subsampled and 1 and 2 are subsampled by 2,
- then hori/vertFactor for comp 0 is 2, for comps 1..2 is 1, and max hori/vert
- factor is 2 (there are 4x as many comp 0 pixels as comps 1 or 2).
- So: loop over y, and over x within y, and decode one MCU (all components),
- advancing x by mcuWidth and y by mcuHeight.
- */
- mcuWidth = 8 * pData->maxHoriFactor;
- mcuHeight = 8 * pData->maxVertFactor;
- /* Reset temp vars in comp data in private; "height" is size of one strip */
- for (comp = 0, pComp = pPriv->compData; comp < pData->nComps; comp++, pComp++) {
- pComp->height = nSrcLines * pComp->vertFactor / pData->maxVertFactor;
- pComp->x = 0;
- pComp->y = 0;
- pComp->lastDC = 0; /* new strip; clear as if a reset/restart */
- }
- /* Loop over y, and over x within y, and encode one MCU (all components),
- advancing x by mcuWidth and y by mcuHeight.
- */
- for (mcuMaxY = 0; mcuMaxY < nSrcLines; mcuMaxY += mcuHeight) {
- for (mcuMaxX = 0; mcuMaxX < pData->width; mcuMaxX += mcuWidth) {
- /* Encode one MCU, all components, to (mcuX, mcuY). For each component
- there are horiFactor * vertFactor 8x8 blocks that go across then down.
- */
- for (comp = 0, pComp = pPriv->compData; comp < pData->nComps; comp++, pComp++) {
- nBytesPerRow = nSrcBytesPerRow[comp];
- pPixels = pSrcPixels[comp];
- for (v = 0, bY = pComp->y; v < pComp->vertFactor; v++, bY += 8) {
- for (h = 0, bX = pComp->x; h < pComp->horiFactor; h++, bX += 8) {
- /* Extract one 8x8 block from position (bX, bY). If
- clipped replicate pixel or above scan line out to 8x8.
- */
- { int nBytesInit;
- int nLines, nBytesM1, *pDst, *pDstLine;
- iljpgPtr pSrc, pSrcLine;
- nLines = pComp->height - bY;
- if (nLines > 8)
- nLines = 8;
- nBytesInit = pComp->width - bX;
- if (nBytesInit > 8)
- nBytesInit = 8;
- if ((nLines > 0) && (nBytesInit > 0)) {
- pSrcLine = pPixels + (bY * nBytesPerRow) + bX;
- pDstLine = pixels;
- /* If clipped; do nLines, replicate at right edge */
- if ((nLines < 8) || (nBytesInit < 8)) {
- int i, j, pixel;
- for (i = 0; i < nLines; i++) {
- pSrc = pSrcLine;
- pSrcLine += nBytesPerRow;
- pDst = pDstLine;
- pDstLine += 8;
- for (j = 0; j < nBytesInit; j++)
- *pDst++ = pixel = *pSrc++;
- for (j = nBytesInit; j < 8; j++)
- *pDst++ = pixel; /* replicate right */
- }
- /* Replicate last dst line out to 8 lines */
- pDst = pDstLine;
- pDstLine -= 8; /* back up one line */
- for (i = nLines; i < 8; i++) {
- for (j = 0; j < 8; j++)
- *pDst++ = pDstLine[j];
- }
- } /* END clipped */
- else { /* all 8x8 available; do simple case */
- nLines--; /* make # lines/bytes - 1 */
- nBytesInit--;
- do {
- nBytesM1 = nBytesInit;
- pSrc = pSrcLine;
- pSrcLine += nBytesPerRow;
- pDst = pDstLine;
- pDstLine += 8;
- do {
- *pDst++ = *pSrc++;
- } while (--nBytesM1 >= 0);
- } while (--nLines >= 0);
- }
- }
- }
- /* Do DCT encoding, from "pixels" back into "pixels" */
- _iljpgEnDCT (pixels, pComp->pScale);
- /* Subtract previous DC from this one, save this one for next */
- { int dc;
- dc = pixels[0];
- pixels[0] = dc - pComp->lastDC;
- pComp->lastDC = dc;
- }
- /* Do Huffman encoding of block */
- if (error = _iljpgEnhuffExecute (pPriv, comp, pixels, stream))
- return error;
- } /* END hori, one 8x8 block */
- } /* END vert */
- pComp->x += pComp->mcuXInc; /* move component one MCU to right */
- } /* END one component */
- } /* END one hori MCU */
- /* Move each component one MCU down, reset to left edge */
- for (comp = 0, pComp = pPriv->compData; comp < pData->nComps; comp++, pComp++) {
- pComp->y += pComp->mcuYInc;
- pComp->x = 0;
- }
- } /* END one vert MCU */
- /* Flush any bits not yet output from Huffman encoding and exit */
- return _iljpgEnhuffFlush (pPriv, stream);
- }
|