19f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
29f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jutils.c
39f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
49f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Copyright (C) 1991-1996, Thomas G. Lane.
59f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file is part of the Independent JPEG Group's software.
69f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * For conditions of distribution and use, see the accompanying README file.
79f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
89f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file contains tables and miscellaneous utility routines needed
99f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * for both compression and decompression.
109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note we prefix all global names with "j" to minimize conflicts with
119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * a surrounding application.
129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define JPEG_INTERNALS
159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jinclude.h"
169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jpeglib.h"
179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * of a DCT block read in natural order (left to right, top to bottom).
229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if 0				/* This table is not actually needed in v6a */
259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectconst int jpeg_zigzag_order[DCTSIZE2] = {
279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   0,  1,  5,  6, 14, 15, 27, 28,
289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   2,  4,  7, 13, 16, 26, 29, 42,
299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   3,  8, 12, 17, 25, 30, 41, 43,
309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   9, 11, 18, 24, 31, 40, 44, 53,
319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  10, 19, 23, 32, 39, 45, 52, 54,
329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  20, 22, 33, 38, 46, 51, 55, 60,
339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  21, 34, 37, 47, 50, 56, 59, 61,
349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  35, 36, 48, 49, 57, 58, 62, 63
359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project};
369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jpeg_natural_order[i] is the natural-order position of the i'th element
419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * of zigzag order.
429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * When reading corrupted data, the Huffman decoders could attempt
449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to reference an entry beyond the end of this array (if the decoded
459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * zero run length reaches past the end of the block).  To prevent
469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * wild stores without adding an inner-loop test, we put some extra
479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * "63"s after the real entries.  This will cause the extra coefficient
489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to be stored in location 63 of the block, not somewhere random.
499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The worst case would be a run-length of 15, which means we need 16
509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * fake entries.
519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectconst int jpeg_natural_order[DCTSIZE2+16] = {
549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  0,  1,  8, 16,  9,  2,  3, 10,
559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 17, 24, 32, 25, 18, 11,  4,  5,
569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 12, 19, 26, 33, 40, 48, 41, 34,
579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 27, 20, 13,  6,  7, 14, 21, 28,
589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 35, 42, 49, 56, 57, 50, 43, 36,
599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 29, 22, 15, 23, 30, 37, 44, 51,
609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 58, 59, 52, 45, 38, 31, 39, 46,
619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 53, 60, 61, 54, 47, 55, 62, 63,
629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 63, 63, 63, 63, 63, 63, 63, 63
649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project};
659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Arithmetic utilities
699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(long)
729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjdiv_round_up (long a, long b)
739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Assumes a >= 0, b > 0 */
759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  return (a + b - 1L) / b;
779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(long)
819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjround_up (long a, long b)
829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Assumes a >= 0, b > 0 */
849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  a += b - 1L;
869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  return a - (a % b);
879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
89f5b94eebe742df1a9bb3941fc0a0ec0137e936efJoseph WenGLOBAL(long)
90f5b94eebe742df1a9bb3941fc0a0ec0137e936efJoseph Wenjmin (long a, long b)
91f5b94eebe742df1a9bb3941fc0a0ec0137e936efJoseph Wen{
92f5b94eebe742df1a9bb3941fc0a0ec0137e936efJoseph Wen  return a < b ? a : b;
93f5b94eebe742df1a9bb3941fc0a0ec0137e936efJoseph Wen}
94f5b94eebe742df1a9bb3941fc0a0ec0137e936efJoseph Wen
959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and coefficient-block arrays.  This won't work on 80x86 because the arrays
989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * are FAR and we're assuming a small-pointer memory model.  However, some
999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * DOS compilers provide far-pointer versions of memcpy() and memset() even
1009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * in the small-model libraries.  These will be used if USE_FMEM is defined.
1019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Otherwise, the routines below do it the hard way.  (The performance cost
1029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * is not all that great, because these routines aren't very heavily used.)
1039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifndef NEED_FAR_POINTERS	/* normal case, same as regular macros */
1069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define FMEMCOPY(dest,src,size)	MEMCOPY(dest,src,size)
1079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define FMEMZERO(target,size)	MEMZERO(target,size)
1089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else				/* 80x86 case, define if we can */
1099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef USE_FMEM
1109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define FMEMCOPY(dest,src,size)	_fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
1119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define FMEMZERO(target,size)	_fmemset((void FAR *)(target), 0, (size_t)(size))
1129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
1139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
1149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void)
1179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjcopy_sample_rows (JSAMPARRAY input_array, int source_row,
1189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		   JSAMPARRAY output_array, int dest_row,
1199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		   int num_rows, JDIMENSION num_cols)
1209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Copy some rows of samples from one place to another.
1219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * num_rows rows are copied from input_array[source_row++]
1229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to output_array[dest_row++]; these areas may overlap for duplication.
1239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The source and destination arrays must be at least as wide as num_cols.
1249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
1269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register JSAMPROW inptr, outptr;
1279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef FMEMCOPY
1289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
1299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else
1309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register JDIMENSION count;
1319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
1329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register int row;
1339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  input_array += source_row;
1359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  output_array += dest_row;
1369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (row = num_rows; row > 0; row--) {
1389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inptr = *input_array++;
1399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    outptr = *output_array++;
1409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef FMEMCOPY
1419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    FMEMCOPY(outptr, inptr, count);
1429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else
1439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (count = num_cols; count > 0; count--)
1449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      *outptr++ = *inptr++;	/* needn't bother with GETJSAMPLE() here */
1459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
1469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
1479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
1489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void)
1519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
1529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		 JDIMENSION num_blocks)
1539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Copy a row of coefficient blocks from one place to another. */
1549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
1559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef FMEMCOPY
1569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
1579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else
1589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register JCOEFPTR inptr, outptr;
1599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register long count;
1609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  inptr = (JCOEFPTR) input_row;
1629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  outptr = (JCOEFPTR) output_row;
1639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
1649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    *outptr++ = *inptr++;
1659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
1669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
1679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
1689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void)
1719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjzero_far (void FAR * target, size_t bytestozero)
1729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Zero out a chunk of FAR memory. */
1739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* This might be sample-array data, block-array data, or alloc_large data. */
1749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
1759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef FMEMZERO
1769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  FMEMZERO(target, bytestozero);
1779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else
1789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register char FAR * ptr = (char FAR *) target;
1799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register size_t count;
1809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (count = bytestozero; count > 0; count--) {
1829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    *ptr++ = 0;
1839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
1849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
1859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
186