Back to index

plt-scheme  4.2.1
jutils.c
Go to the documentation of this file.
00001 /*
00002  * jutils.c
00003  *
00004  * Copyright (C) 1991-1996, Thomas G. Lane.
00005  * This file is part of the Independent JPEG Group's software.
00006  * For conditions of distribution and use, see the accompanying README file.
00007  *
00008  * This file contains tables and miscellaneous utility routines needed
00009  * for both compression and decompression.
00010  * Note we prefix all global names with "j" to minimize conflicts with
00011  * a surrounding application.
00012  */
00013 
00014 #define JPEG_INTERNALS
00015 #include "jinclude.h"
00016 #include "jpeglib.h"
00017 
00018 
00019 /*
00020  * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
00021  * of a DCT block read in natural order (left to right, top to bottom).
00022  */
00023 
00024 #if 0                       /* This table is not actually needed in v6a */
00025 
00026 const int jpeg_zigzag_order[DCTSIZE2] = {
00027    0,  1,  5,  6, 14, 15, 27, 28,
00028    2,  4,  7, 13, 16, 26, 29, 42,
00029    3,  8, 12, 17, 25, 30, 41, 43,
00030    9, 11, 18, 24, 31, 40, 44, 53,
00031   10, 19, 23, 32, 39, 45, 52, 54,
00032   20, 22, 33, 38, 46, 51, 55, 60,
00033   21, 34, 37, 47, 50, 56, 59, 61,
00034   35, 36, 48, 49, 57, 58, 62, 63
00035 };
00036 
00037 #endif
00038 
00039 /*
00040  * jpeg_natural_order[i] is the natural-order position of the i'th element
00041  * of zigzag order.
00042  *
00043  * When reading corrupted data, the Huffman decoders could attempt
00044  * to reference an entry beyond the end of this array (if the decoded
00045  * zero run length reaches past the end of the block).  To prevent
00046  * wild stores without adding an inner-loop test, we put some extra
00047  * "63"s after the real entries.  This will cause the extra coefficient
00048  * to be stored in location 63 of the block, not somewhere random.
00049  * The worst case would be a run-length of 15, which means we need 16
00050  * fake entries.
00051  */
00052 
00053 const int jpeg_natural_order[DCTSIZE2+16] = {
00054   0,  1,  8, 16,  9,  2,  3, 10,
00055  17, 24, 32, 25, 18, 11,  4,  5,
00056  12, 19, 26, 33, 40, 48, 41, 34,
00057  27, 20, 13,  6,  7, 14, 21, 28,
00058  35, 42, 49, 56, 57, 50, 43, 36,
00059  29, 22, 15, 23, 30, 37, 44, 51,
00060  58, 59, 52, 45, 38, 31, 39, 46,
00061  53, 60, 61, 54, 47, 55, 62, 63,
00062  63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
00063  63, 63, 63, 63, 63, 63, 63, 63
00064 };
00065 
00066 
00067 /*
00068  * Arithmetic utilities
00069  */
00070 
00071 GLOBAL(long)
00072 jdiv_round_up (long a, long b)
00073 /* Compute a/b rounded up to next integer, ie, ceil(a/b) */
00074 /* Assumes a >= 0, b > 0 */
00075 {
00076   return (a + b - 1L) / b;
00077 }
00078 
00079 
00080 GLOBAL(long)
00081 jround_up (long a, long b)
00082 /* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
00083 /* Assumes a >= 0, b > 0 */
00084 {
00085   a += b - 1L;
00086   return a - (a % b);
00087 }
00088 
00089 
00090 /* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
00091  * and coefficient-block arrays.  This won't work on 80x86 because the arrays
00092  * are FAR and we're assuming a small-pointer memory model.  However, some
00093  * DOS compilers provide far-pointer versions of memcpy() and memset() even
00094  * in the small-model libraries.  These will be used if USE_FMEM is defined.
00095  * Otherwise, the routines below do it the hard way.  (The performance cost
00096  * is not all that great, because these routines aren't very heavily used.)
00097  */
00098 
00099 #ifndef NEED_FAR_POINTERS   /* normal case, same as regular macros */
00100 #define FMEMCOPY(dest,src,size)    MEMCOPY(dest,src,size)
00101 #define FMEMZERO(target,size)      MEMZERO(target,size)
00102 #else                       /* 80x86 case, define if we can */
00103 #ifdef USE_FMEM
00104 #define FMEMCOPY(dest,src,size)    _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
00105 #define FMEMZERO(target,size)      _fmemset((void FAR *)(target), 0, (size_t)(size))
00106 #endif
00107 #endif
00108 
00109 
00110 GLOBAL(void)
00111 jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
00112                  JSAMPARRAY output_array, int dest_row,
00113                  int num_rows, JDIMENSION num_cols)
00114 /* Copy some rows of samples from one place to another.
00115  * num_rows rows are copied from input_array[source_row++]
00116  * to output_array[dest_row++]; these areas may overlap for duplication.
00117  * The source and destination arrays must be at least as wide as num_cols.
00118  */
00119 {
00120   register JSAMPROW inptr, outptr;
00121 #ifdef FMEMCOPY
00122   register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
00123 #else
00124   register JDIMENSION count;
00125 #endif
00126   register int row;
00127 
00128   input_array += source_row;
00129   output_array += dest_row;
00130 
00131   for (row = num_rows; row > 0; row--) {
00132     inptr = *input_array++;
00133     outptr = *output_array++;
00134 #ifdef FMEMCOPY
00135     FMEMCOPY(outptr, inptr, count);
00136 #else
00137     for (count = num_cols; count > 0; count--)
00138       *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
00139 #endif
00140   }
00141 }
00142 
00143 
00144 GLOBAL(void)
00145 jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
00146                JDIMENSION num_blocks)
00147 /* Copy a row of coefficient blocks from one place to another. */
00148 {
00149 #ifdef FMEMCOPY
00150   FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
00151 #else
00152   register JCOEFPTR inptr, outptr;
00153   register long count;
00154 
00155   inptr = (JCOEFPTR) input_row;
00156   outptr = (JCOEFPTR) output_row;
00157   for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
00158     *outptr++ = *inptr++;
00159   }
00160 #endif
00161 }
00162 
00163 
00164 GLOBAL(void)
00165 jzero_far (void FAR * target, size_t bytestozero)
00166 /* Zero out a chunk of FAR memory. */
00167 /* This might be sample-array data, block-array data, or alloc_large data. */
00168 {
00169 #ifdef FMEMZERO
00170   FMEMZERO(target, bytestozero);
00171 #else
00172   register char FAR * ptr = (char FAR *) target;
00173   register size_t count;
00174 
00175   for (count = bytestozero; count > 0; count--) {
00176     *ptr++ = 0;
00177   }
00178 #endif
00179 }