quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
		    JSAMPARRAY output_buf, int num_rows)
/* General case, with Floyd-Steinberg dithering */
{
  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
  register LOCFSERROR cur;	/* current error or pixel value */
  LOCFSERROR belowerr;		/* error for pixel below cur */
  LOCFSERROR bpreverr;		/* error for below/prev col */
  LOCFSERROR bnexterr;		/* error for below/next col */
  LOCFSERROR delta;
  register FSERRPTR errorptr;	/* => fserrors[] at column before current */
  register JSAMPROW input_ptr;
  register JSAMPROW output_ptr;
  JSAMPROW colorindex_ci;
  JSAMPROW colormap_ci;
  int pixcode;
  int nc = cinfo->out_color_components;
  int dir;			/* 1 for left-to-right, -1 for right-to-left */
  int dirnc;			/* dir * nc */
  int ci;
  int row;
  JDIMENSION col;
  JDIMENSION width = cinfo->output_width;
  JSAMPLE *range_limit = cinfo->sample_range_limit;
  SHIFT_TEMPS

  for (row = 0; row < num_rows; row++) {
    /* Initialize output values to 0 so can process components separately */
    jzero_far((void FAR *) output_buf[row],
	      (size_t) (width * SIZEOF(JSAMPLE)));
    for (ci = 0; ci < nc; ci++) {
      input_ptr = input_buf[row] + ci;
      output_ptr = output_buf[row];
      if (cquantize->on_odd_row) {
	/* work right to left in this row */
	input_ptr += (width-1) * nc; /* so point to rightmost pixel */
	output_ptr += width-1;
	dir = -1;
	dirnc = -nc;
	errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
      } else {
	/* work left to right in this row */
	dir = 1;
	dirnc = nc;
	errorptr = cquantize->fserrors[ci]; /* => entry before first column */
      }
      colorindex_ci = cquantize->colorindex[ci];
      colormap_ci = cquantize->sv_colormap[ci];
      /* Preset error values: no error propagated to first pixel from left */
      cur = 0;
      /* and no error propagated to row below yet */
      belowerr = bpreverr = 0;

      for (col = width; col > 0; col--) {
	/* cur holds the error propagated from the previous pixel on the
	 * current line.  Add the error propagated from the previous line
	 * to form the complete error correction term for this pixel, and
	 * round the error term (which is expressed * 16) to an integer.
	 * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
	 * for either sign of the error value.
	 * Note: errorptr points to *previous* column's array entry.
	 */
	cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
	/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
	 * The maximum error is +- MAXJSAMPLE; this sets the required size
	 * of the range_limit array.
	 */
	cur += GETJSAMPLE(*input_ptr);
	cur = GETJSAMPLE(range_limit[cur]);
	/* Select output value, accumulate into output code for this pixel */
	pixcode = GETJSAMPLE(colorindex_ci[cur]);
	*output_ptr += (JSAMPLE) pixcode;
	/* Compute actual representation error at this pixel */
	/* Note: we can do this even though we don't have the final */
	/* pixel code, because the colormap is orthogonal. */
	cur -= GETJSAMPLE(colormap_ci[pixcode]);
	/* Compute error fractions to be propagated to adjacent pixels.
	 * Add these into the running sums, and simultaneously shift the
	 * next-line error sums left by 1 column.
	 */
	bnexterr = cur;
	delta = cur * 2;
	cur += delta;		/* form error * 3 */
	errorptr[0] = (FSERROR) (bpreverr + cur);
	cur += delta;		/* form error * 5 */
	bpreverr = belowerr + cur;
	belowerr = bnexterr;
	cur += delta;		/* form error * 7 */
	/* At this point cur contains the 7/16 error value to be propagated
	 * to the next pixel on the current line, and all the errors for the
	 * next line have been shifted over. We are therefore ready to move on.
	 */
	input_ptr += dirnc;	/* advance input ptr to next column */
	output_ptr += dir;	/* advance output ptr to next column */
	errorptr += dir;	/* advance errorptr to current column */
      }
      /* Post-loop cleanup: we must unload the final error value into the
       * final fserrors[] entry.  Note we need not unload belowerr because
       * it is for the dummy column before or after the actual array.
       */
      errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
    }
    cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
  }
}
Beispiel #2
0
get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit colormap indexes */
{
  bmp_source_ptr source = (bmp_source_ptr)sinfo;
  register JSAMPARRAY colormap = source->colormap;
  int cmaplen = source->cmap_length;
  JSAMPARRAY image_ptr;
  register int t;
  register JSAMPROW inptr, outptr;
  register JDIMENSION col;

  if (source->use_inversion_array) {
    /* Fetch next row from virtual array */
    source->source_row--;
    image_ptr = (*cinfo->mem->access_virt_sarray)
      ((j_common_ptr)cinfo, source->whole_image,
       source->source_row, (JDIMENSION)1, FALSE);
    inptr = image_ptr[0];
  } else {
    if (!ReadOK(source->pub.input_file, source->iobuffer, source->row_width))
      ERREXIT(cinfo, JERR_INPUT_EOF);
    inptr = source->iobuffer;
  }

  /* Expand the colormap indexes to real data */
  outptr = source->pub.buffer[0];
  if (cinfo->in_color_space == JCS_GRAYSCALE) {
    for (col = cinfo->image_width; col > 0; col--) {
      t = GETJSAMPLE(*inptr++);
      if (t >= cmaplen)
        ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
      *outptr++ = colormap[0][t];
    }
  } else if (cinfo->in_color_space == JCS_CMYK) {
    for (col = cinfo->image_width; col > 0; col--) {
      t = GETJSAMPLE(*inptr++);
      if (t >= cmaplen)
        ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
      rgb_to_cmyk(colormap[0][t], colormap[1][t], colormap[2][t], outptr,
                  outptr + 1, outptr + 2, outptr + 3);
      outptr += 4;
    }
  } else {
    register int rindex = rgb_red[cinfo->in_color_space];
    register int gindex = rgb_green[cinfo->in_color_space];
    register int bindex = rgb_blue[cinfo->in_color_space];
    register int aindex = alpha_index[cinfo->in_color_space];
    register int ps = rgb_pixelsize[cinfo->in_color_space];

    if (aindex >= 0) {
      for (col = cinfo->image_width; col > 0; col--) {
        t = GETJSAMPLE(*inptr++);
        if (t >= cmaplen)
          ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
        outptr[rindex] = colormap[0][t];
        outptr[gindex] = colormap[1][t];
        outptr[bindex] = colormap[2][t];
        outptr[aindex] = 0xFF;
        outptr += ps;
      }
    } else {
      for (col = cinfo->image_width; col > 0; col--) {
        t = GETJSAMPLE(*inptr++);
        if (t >= cmaplen)
          ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
        outptr[rindex] = colormap[0][t];
        outptr[gindex] = colormap[1][t];
        outptr[bindex] = colormap[2][t];
        outptr += ps;
      }
    }
  }

  return 1;
}
LOCAL void
extract_block (JSAMPARRAY input_data, int start_row, long start_col,
	       JBLOCK output_data, QUANT_TBL_PTR quanttbl)
/* Extract one 8x8 block from the specified location in the sample array; */
/* perform forward DCT, quantization scaling, and zigzag reordering on it. */
{
  /* This routine is heavily used, so it's worth coding it tightly. */
  DCTBLOCK block;
#ifdef DCT_ERR_STATS
  DCTBLOCK svblock;		/* saves input data for comparison */
#endif

  { register JSAMPROW elemptr;
    register DCTELEM *localblkptr = block;
    register int elemr;

    for (elemr = DCTSIZE; elemr > 0; elemr--) {
      elemptr = input_data[start_row++] + start_col;
#if DCTSIZE == 8		/* unroll the inner loop */
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
#else
      { register int elemc;
	for (elemc = DCTSIZE; elemc > 0; elemc--) {
	  *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
	}
      }
#endif
    }
  }

#ifdef DCT_ERR_STATS
  MEMCOPY(svblock, block, SIZEOF(DCTBLOCK));
#endif

  j_fwd_dct(block);

  { register JCOEF temp;
    register QUANT_VAL qval;
    register int i;

    for (i = 0; i < DCTSIZE2; i++) {
      qval = *quanttbl++;
      temp = (JCOEF) block[ZAG[i]];
      /* Divide the coefficient value by qval, ensuring proper rounding.
       * Since C does not specify the direction of rounding for negative
       * quotients, we have to force the dividend positive for portability.
       *
       * In most files, at least half of the output values will be zero
       * (at default quantization settings, more like three-quarters...)
       * so we should ensure that this case is fast.  On many machines,
       * a comparison is enough cheaper than a divide to make a special test
       * a win.  Since both inputs will be nonnegative, we need only test
       * for a < b to discover whether a/b is 0.
       * If your machine's division is fast enough, define FAST_DIVIDE.
       */
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b)	a /= b
#else
#define DIVIDE_BY(a,b)	(a >= b) ? (a /= b) : (a = 0)
#endif
      if (temp < 0) {
	temp = -temp;
	temp += qval>>1;	/* for rounding */
	DIVIDE_BY(temp, qval);
	temp = -temp;
      } else {
	temp += qval>>1;	/* for rounding */
	DIVIDE_BY(temp, qval);
      }
      *output_data++ = temp;
    }
Beispiel #4
0
finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
  rle_hdr header;		/* Output file information */
  rle_pixel **rle_row, *red, *green, *blue;
  JSAMPROW output_row;
  char cmapcomment[80];
  int row, col;
  int ci;
#ifdef LIBJPEG_PROGRESS_REPORT
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
#endif

  /* Initialize the header info */
  header = *rle_hdr_init(NULL);
  header.rle_file = dest->pub.output_file;
  header.xmin     = 0;
  header.xmax     = cinfo->output_width  - 1;
  header.ymin     = 0;
  header.ymax     = cinfo->output_height - 1;
  header.alpha    = 0;
  header.ncolors  = cinfo->output_components;
  for (ci = 0; ci < cinfo->output_components; ci++) {
    RLE_SET_BIT(header, ci);
  }
  if (cinfo->quantize_colors) {
    header.ncmap   = cinfo->out_color_components;
    header.cmaplen = CMAPBITS;
    header.cmap    = dest->colormap;
    /* Add a comment to the output image with the true colormap length. */
    sprintf(cmapcomment, "color_map_length=%d", cinfo->actual_number_of_colors);
    rle_putcom(cmapcomment, &header);
  }

  /* Emit the RLE header and color map (if any) */
  rle_put_setup(&header);

  /* Now output the RLE data from our virtual array.
   * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
   * and (b) we are not on a machine where FAR pointers differ from regular.
   */

#ifdef LIBJPEG_PROGRESS_REPORT
  if (progress != NULL) {
    progress->pub.pass_limit = cinfo->output_height;
    progress->pub.pass_counter = 0;
    (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
  }
#endif

  if (cinfo->output_components == 1) {
    for (row = cinfo->output_height-1; row >= 0; row--) {
      rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
        ((j_common_ptr) cinfo, dest->image,
	 (JDIMENSION) row, (JDIMENSION) 1, FALSE);
      rle_putrow(rle_row, (int) cinfo->output_width, &header);
#ifdef LIBJPEG_PROGRESS_REPORT
      if (progress != NULL) {
        progress->pub.pass_counter++;
        (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
      }
#endif
    }
  } else {
    for (row = cinfo->output_height-1; row >= 0; row--) {
      rle_row = (rle_pixel **) dest->rle_row;
      output_row = * (*cinfo->mem->access_virt_sarray)
        ((j_common_ptr) cinfo, dest->image,
	 (JDIMENSION) row, (JDIMENSION) 1, FALSE);
      red = rle_row[0];
      green = rle_row[1];
      blue = rle_row[2];
      for (col = cinfo->output_width; col > 0; col--) {
        *red++ = GETJSAMPLE(*output_row++);
        *green++ = GETJSAMPLE(*output_row++);
        *blue++ = GETJSAMPLE(*output_row++);
      }
      rle_putrow(rle_row, (int) cinfo->output_width, &header);
#ifdef LIBJPEG_PROGRESS_REPORT
      if (progress != NULL) {
        progress->pub.pass_counter++;
        (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
      }
#endif
    }
  }

#ifdef LIBJPEG_PROGRESS_REPORT
  if (progress != NULL)
    progress->completed_extra_passes++;
#endif

  /* Emit file trailer */
  rle_puteof(&header);
  fflush(dest->pub.output_file);
  if (ferror(dest->pub.output_file))
    ERREXIT(cinfo, JERR_FILE_WRITE);
}
Beispiel #5
0
start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
  size_t cmapsize;
  int i, ci;
#ifdef LIBJPEG_PROGRESS_REPORT
  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
#endif

  /*
   * Make sure the image can be stored in RLE format.
   *
   * - RLE stores image dimensions as *signed* 16 bit integers.  JPEG
   *   uses unsigned, so we have to check the width.
   *
   * - Colorspace is expected to be grayscale or RGB.
   *
   * - The number of channels (components) is expected to be 1 (grayscale/
   *   pseudocolor) or 3 (truecolor/directcolor).
   *   (could be 2 or 4 if using an alpha channel, but we aren't)
   */

  if (cinfo->output_width > 32767 || cinfo->output_height > 32767)
    ERREXIT2(cinfo, JERR_RLE_DIMENSIONS, cinfo->output_width, 
	     cinfo->output_height);

  if (cinfo->out_color_space != JCS_GRAYSCALE &&
      cinfo->out_color_space != JCS_RGB)
    ERREXIT(cinfo, JERR_RLE_COLORSPACE);

  if (cinfo->output_components != 1 && cinfo->output_components != 3)
    ERREXIT1(cinfo, JERR_RLE_TOOMANYCHANNELS, cinfo->num_components);

  /* Convert colormap, if any, to RLE format. */

  dest->colormap = NULL;

  if (cinfo->quantize_colors) {
    /* Allocate storage for RLE-style cmap, zero any extra entries */
    cmapsize = cinfo->out_color_components * CMAPLENGTH * SIZEOF(rle_map);
    dest->colormap = (rle_map *) (*cinfo->mem->alloc_small)
      ((j_common_ptr) cinfo, JPOOL_IMAGE, cmapsize);
    MEMZERO(dest->colormap, cmapsize);

    /* Save away data in RLE format --- note 8-bit left shift! */
    /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
    for (ci = 0; ci < cinfo->out_color_components; ci++) {
      for (i = 0; i < cinfo->actual_number_of_colors; i++) {
        dest->colormap[ci * CMAPLENGTH + i] =
          GETJSAMPLE(cinfo->colormap[ci][i]) << 8;
      }
    }
  }

  /* Set the output buffer to the first row */
  dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
    ((j_common_ptr) cinfo, dest->image, (JDIMENSION) 0, (JDIMENSION) 1, TRUE);
  dest->pub.buffer_height = 1;

  dest->pub.put_pixel_rows = rle_put_pixel_rows;

#ifdef LIBJPEG_PROGRESS_REPORT
  if (progress != NULL) {
    progress->total_extra_passes++;  /* count file writing as separate pass */
  }
#endif
}
Beispiel #6
0
void
il_quantize_fs_dither(il_container *ic, const uint8 *mask,
                      const uint8 *input_buf, int x_offset,
                      uint8 XP_HUGE *output_buf, int width)
{
    my_cquantize_ptr cquantize;
    register LOCFSERROR r_cur, g_cur, b_cur;       /* current error or pixel
                                                      value */
    LOCFSERROR r_belowerr, g_belowerr, b_belowerr; /* error for pixel below
                                                      cur */
    LOCFSERROR r_bpreverr, g_bpreverr, b_bpreverr; /* error for below/prev
                                                      col */
    LOCFSERROR r_bnexterr, g_bnexterr, b_bnexterr; /* error for below/next
                                                      col */
    LOCFSERROR delta;
    FSERRPTR r_errorptr, g_errorptr, b_errorptr;   /* fserrors[] at column
                                                      before current */
    const JSAMPLE* input_ptr;
    JSAMPLE XP_HUGE * output_ptr;
    IL_ColorMap *cmap = &ic->image->header.color_space->cmap;
    IL_RGB *map = cmap->map;              /* The colormap array. */
    IL_RGB *map_entry;                    /* Current entry in the colormap. */
    uint8 *lookup_table = cmap->table;    /* Lookup table for the colormap. */
    const uint8 *maskp;
    uint8 map_index;
    int dir;                   /* 1 for left-to-right, -1 for right-to-left */
    JDIMENSION col;
    JSAMPLE *range_limit = the_sample_range_limit;
    SHIFT_TEMPS

    cquantize = (my_cquantize_ptr) ic->quantize;
    
    output_buf += x_offset;

    /* Initialize output values to 0 so can process components separately */
    if (mask) {
        output_ptr = output_buf;
        maskp = mask;
        for (col = width; col > 0; col--)
            *output_ptr++ &= ~*maskp++;
    } else {
        XP_BZERO((void XP_HUGE *) output_buf,
                 (size_t) (width * SIZEOF(JSAMPLE)));
    }

    input_ptr = input_buf;
    output_ptr = output_buf;
    maskp = mask;
    if (cquantize->on_odd_row) {
        int total_offset;

        /* work right to left in this row */
        input_ptr += 3 * width - 1; /* so point to the blue sample of the
                                       rightmost pixel */
        output_ptr += width-1;
        dir = -1;
        /* => entry after last column */
        total_offset = x_offset + (width + 1);
        r_errorptr = cquantize->fserrors[0] + total_offset;
        g_errorptr = cquantize->fserrors[1] + total_offset;
        b_errorptr = cquantize->fserrors[2] + total_offset;
        maskp += (width - 1);
    } 
    else {
        /* work left to right in this row */
        dir = 1;
        /* => entry before first column */
        r_errorptr = cquantize->fserrors[0] + x_offset;
        g_errorptr = cquantize->fserrors[1] + x_offset;
        b_errorptr = cquantize->fserrors[2] + x_offset;
    }

    /* Preset error values: no error propagated to first pixel from left */
    r_cur = g_cur = b_cur = 0;

    /* and no error propagated to row below yet */
    r_belowerr = g_belowerr = b_belowerr = 0;
    r_bpreverr = g_bpreverr = b_bpreverr = 0;

    for (col = width; col > 0; col--) {
        /* cur holds the error propagated from the previous pixel on the
         * current line.  Add the error propagated from the previous line
         * to form the complete error correction term for this pixel, and
         * round the error term (which is expressed * 16) to an integer.
         * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
         * for either sign of the error value.
         * Note: errorptr points to *previous* column's array entry.
         */
        r_cur = RIGHT_SHIFT(r_cur + r_errorptr[dir] + 8, 4);
        g_cur = RIGHT_SHIFT(g_cur + g_errorptr[dir] + 8, 4);
        b_cur = RIGHT_SHIFT(b_cur + b_errorptr[dir] + 8, 4);

        /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
         * The maximum error is +- MAXJSAMPLE; this sets the required size
         * of the range_limit array.
         */
        if (dir > 0) {
            r_cur += GETJSAMPLE(*input_ptr);
            r_cur = GETJSAMPLE(range_limit[r_cur]);
            input_ptr++;
            g_cur += GETJSAMPLE(*input_ptr);
            g_cur = GETJSAMPLE(range_limit[g_cur]);
            input_ptr++;
            b_cur += GETJSAMPLE(*input_ptr);
            b_cur = GETJSAMPLE(range_limit[b_cur]);
            input_ptr++;
        }
        else {
            b_cur += GETJSAMPLE(*input_ptr);
            b_cur = GETJSAMPLE(range_limit[b_cur]);
            input_ptr--;
            g_cur += GETJSAMPLE(*input_ptr);
            g_cur = GETJSAMPLE(range_limit[g_cur]);
            input_ptr--;
            r_cur += GETJSAMPLE(*input_ptr);
            r_cur = GETJSAMPLE(range_limit[r_cur]);
            input_ptr--;
        }

        /* Select output value, accumulate into output code for this pixel */
        map_index = COLORMAP_INDEX(lookup_table, r_cur, g_cur, b_cur);
        if (mask) {
            if (*maskp)
                *output_ptr = map_index;
            maskp += dir;
        } else {
            *output_ptr = map_index;
        }

        /* Compute the actual representation error at this pixel */
        map_entry = map + map_index;
        r_cur -= GETJSAMPLE(map_entry->red);
        g_cur -= GETJSAMPLE(map_entry->green);
        b_cur -= GETJSAMPLE(map_entry->blue);

        /* Compute error fractions to be propagated to adjacent pixels.
         * Add these into the running sums, and simultaneously shift the
         * next-line error sums left by 1 column.
         */
        r_bnexterr = r_cur;
        delta = r_cur * 2;
        r_cur += delta;		/* form error * 3 */
        r_errorptr[0] = (FSERROR) (r_bpreverr + r_cur);
        r_cur += delta;		/* form error * 5 */
        r_bpreverr = r_belowerr + r_cur;
        r_belowerr = r_bnexterr;
        r_cur += delta;		/* form error * 7 */

        g_bnexterr = g_cur;
        delta = g_cur * 2;
        g_cur += delta;		/* form error * 3 */
        g_errorptr[0] = (FSERROR) (g_bpreverr + g_cur);
        g_cur += delta;		/* form error * 5 */
        g_bpreverr = g_belowerr + g_cur;
        g_belowerr = g_bnexterr;
        g_cur += delta;		/* form error * 7 */

        b_bnexterr = b_cur;
        delta = b_cur * 2;
        b_cur += delta;		/* form error * 3 */
        b_errorptr[0] = (FSERROR) (b_bpreverr + b_cur);
        b_cur += delta;		/* form error * 5 */
        b_bpreverr = b_belowerr + b_cur;
        b_belowerr = b_bnexterr;
        b_cur += delta;		/* form error * 7 */

        /* At this point cur contains the 7/16 error value to be propagated
         * to the next pixel on the current line, and all the errors for the
         * next line have been shifted over. We are therefore ready to move on.
         * Note: the input_ptr has already been advanced.
         */
        output_ptr += dir;	/* advance output ptr to next column */
        r_errorptr += dir;	/* advance errorptr to current column */
        g_errorptr += dir;	/* advance errorptr to current column */
        b_errorptr += dir;	/* advance errorptr to current column */
    }
    
    /* Post-loop cleanup: we must unload the final error value into the
     * final fserrors[] entry.  Note we need not unload belowerr because
     * it is for the dummy column before or after the actual array.
     */
    r_errorptr[0] = (FSERROR) r_bpreverr; /* unload prev err into array */
    g_errorptr[0] = (FSERROR) g_bpreverr; /* unload prev err into array */
    b_errorptr[0] = (FSERROR) b_bpreverr; /* unload prev err into array */

    cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
}
Beispiel #7
0
METHODDEF void
fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
                           JSAMPARRAY input_data, JSAMPARRAY output_data)
{
	int outrow;
	JDIMENSION colctr;
	JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
	register JSAMPROW inptr, above_ptr, below_ptr, outptr;
	INT32 membersum, neighsum, memberscale, neighscale;
	int colsum, lastcolsum, nextcolsum;

	/* Expand input data enough to let all the output samples be generated
	 * by the standard loop.  Special-casing padded output would be more
	 * efficient.
	 */
	expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
	                  cinfo->image_width, output_cols);

	/* Each of the eight neighbor pixels contributes a fraction SF to the
	 * smoothed pixel, while the main pixel contributes (1-8*SF).  In order
	 * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
	 * Also recall that SF = smoothing_factor / 1024.
	 */

	memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
	neighscale = cinfo->smoothing_factor * 64; /* scaled SF */

	for(outrow = 0; outrow < compptr->v_samp_factor; outrow++)
	{
		outptr = output_data[outrow];
		inptr = input_data[outrow];
		above_ptr = input_data[outrow - 1];
		below_ptr = input_data[outrow + 1];

		/* Special case for first column */
		colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
		         GETJSAMPLE(*inptr);
		membersum = GETJSAMPLE(*inptr++);
		nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
		             GETJSAMPLE(*inptr);
		neighsum = colsum + (colsum - membersum) + nextcolsum;
		membersum = membersum * memberscale + neighsum * neighscale;
		*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
		lastcolsum = colsum;
		colsum = nextcolsum;

		for(colctr = output_cols - 2; colctr > 0; colctr--)
		{
			membersum = GETJSAMPLE(*inptr++);
			above_ptr++;
			below_ptr++;
			nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
			             GETJSAMPLE(*inptr);
			neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
			membersum = membersum * memberscale + neighsum * neighscale;
			*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
			lastcolsum = colsum;
			colsum = nextcolsum;
		}

		/* Special case for last column */
		membersum = GETJSAMPLE(*inptr);
		neighsum = lastcolsum + (colsum - membersum) + colsum;
		membersum = membersum * memberscale + neighsum * neighscale;
		*outptr = (JSAMPLE)((membersum + 32768) >> 16);

	}
}
Beispiel #8
0
jpeg_fdct_ifast (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
{
  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
  DCTELEM tmp10, tmp11, tmp12, tmp13;
  DCTELEM z1, z2, z3, z4, z5, z11, z13;
  DCTELEM *dataptr;
  JSAMPROW elemptr;
  int ctr;
  SHIFT_TEMPS

  /* Pass 1: process rows. */

  dataptr = data;
  for (ctr = 0; ctr < DCTSIZE; ctr++) {
    elemptr = sample_data[ctr] + start_col;

    /* Load data into workspace */
    tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]);
    tmp7 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[7]);
    tmp1 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[6]);
    tmp6 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[6]);
    tmp2 = GETJSAMPLE(elemptr[2]) + GETJSAMPLE(elemptr[5]);
    tmp5 = GETJSAMPLE(elemptr[2]) - GETJSAMPLE(elemptr[5]);
    tmp3 = GETJSAMPLE(elemptr[3]) + GETJSAMPLE(elemptr[4]);
    tmp4 = GETJSAMPLE(elemptr[3]) - GETJSAMPLE(elemptr[4]);

    /* Even part */

    tmp10 = tmp0 + tmp3;	/* phase 2 */
    tmp13 = tmp0 - tmp3;
    tmp11 = tmp1 + tmp2;
    tmp12 = tmp1 - tmp2;

    /* Apply unsigned->signed conversion */
    dataptr[0] = tmp10 + tmp11 - 8 * CENTERJSAMPLE; /* phase 3 */
    dataptr[4] = tmp10 - tmp11;

    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
    dataptr[2] = tmp13 + z1;	/* phase 5 */
    dataptr[6] = tmp13 - z1;

    /* Odd part */

    tmp10 = tmp4 + tmp5;	/* phase 2 */
    tmp11 = tmp5 + tmp6;
    tmp12 = tmp6 + tmp7;

    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */

    z11 = tmp7 + z3;		/* phase 5 */
    z13 = tmp7 - z3;

    dataptr[5] = z13 + z2;	/* phase 6 */
    dataptr[3] = z13 - z2;
    dataptr[1] = z11 + z4;
    dataptr[7] = z11 - z4;

    dataptr += DCTSIZE;		/* advance pointer to next row */
  }

  /* Pass 2: process columns. */

  dataptr = data;
  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];

    /* Even part */

    tmp10 = tmp0 + tmp3;	/* phase 2 */
    tmp13 = tmp0 - tmp3;
    tmp11 = tmp1 + tmp2;
    tmp12 = tmp1 - tmp2;

    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
    dataptr[DCTSIZE*4] = tmp10 - tmp11;

    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
    dataptr[DCTSIZE*6] = tmp13 - z1;

    /* Odd part */

    tmp10 = tmp4 + tmp5;	/* phase 2 */
    tmp11 = tmp5 + tmp6;
    tmp12 = tmp6 + tmp7;

    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */

    z11 = tmp7 + z3;		/* phase 5 */
    z13 = tmp7 - z3;

    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
    dataptr[DCTSIZE*3] = z13 - z2;
    dataptr[DCTSIZE*1] = z11 + z4;
    dataptr[DCTSIZE*7] = z11 - z4;

    dataptr++;			/* advance pointer to next column */
  }
}
Beispiel #9
0
h2v2_merged_upsample_internal (j_decompress_ptr cinfo,
                               JSAMPIMAGE input_buf,
                               JDIMENSION in_row_group_ctr,
                               JSAMPARRAY output_buf)
{
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  register int y, cred, cgreen, cblue;
  int cb, cr;
  register JSAMPROW outptr0, outptr1;
  JSAMPROW inptr00, inptr01, inptr1, inptr2;
  JDIMENSION col;
  /* copy these pointers into registers if possible */
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
  int * Crrtab = upsample->Cr_r_tab;
  int * Cbbtab = upsample->Cb_b_tab;
  INT32 * Crgtab = upsample->Cr_g_tab;
  INT32 * Cbgtab = upsample->Cb_g_tab;
  SHIFT_TEMPS

  inptr00 = input_buf[0][in_row_group_ctr*2];
  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  inptr1 = input_buf[1][in_row_group_ctr];
  inptr2 = input_buf[2][in_row_group_ctr];
  outptr0 = output_buf[0];
  outptr1 = output_buf[1];
  /* Loop for each group of output pixels */
  for (col = cinfo->output_width >> 1; col > 0; col--) {
    /* Do the chroma part of the calculation */
    cb = GETJSAMPLE(*inptr1++);
    cr = GETJSAMPLE(*inptr2++);
    cred = Crrtab[cr];
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    cblue = Cbbtab[cb];
    /* Fetch 4 Y values and emit 4 pixels */
    y  = GETJSAMPLE(*inptr00++);
    outptr0[RGB_RED] =   range_limit[y + cred];
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
#ifdef RGB_ALPHA
    outptr0[RGB_ALPHA] = 0xFF;
#endif
    outptr0 += RGB_PIXELSIZE;
    y  = GETJSAMPLE(*inptr00++);
    outptr0[RGB_RED] =   range_limit[y + cred];
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
#ifdef RGB_ALPHA
    outptr0[RGB_ALPHA] = 0xFF;
#endif
    outptr0 += RGB_PIXELSIZE;
    y  = GETJSAMPLE(*inptr01++);
    outptr1[RGB_RED] =   range_limit[y + cred];
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
#ifdef RGB_ALPHA
    outptr1[RGB_ALPHA] = 0xFF;
#endif
    outptr1 += RGB_PIXELSIZE;
    y  = GETJSAMPLE(*inptr01++);
    outptr1[RGB_RED] =   range_limit[y + cred];
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
#ifdef RGB_ALPHA
    outptr1[RGB_ALPHA] = 0xFF;
#endif
    outptr1 += RGB_PIXELSIZE;
  }
  /* If image width is odd, do the last output column separately */
  if (cinfo->output_width & 1) {
    cb = GETJSAMPLE(*inptr1);
    cr = GETJSAMPLE(*inptr2);
    cred = Crrtab[cr];
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    cblue = Cbbtab[cb];
    y  = GETJSAMPLE(*inptr00);
    outptr0[RGB_RED] =   range_limit[y + cred];
    outptr0[RGB_GREEN] = range_limit[y + cgreen];
    outptr0[RGB_BLUE] =  range_limit[y + cblue];
#ifdef RGB_ALPHA
    outptr0[RGB_ALPHA] = 0xFF;
#endif
    y  = GETJSAMPLE(*inptr01);
    outptr1[RGB_RED] =   range_limit[y + cred];
    outptr1[RGB_GREEN] = range_limit[y + cgreen];
    outptr1[RGB_BLUE] =  range_limit[y + cblue];
#ifdef RGB_ALPHA
    outptr1[RGB_ALPHA] = 0xFF;
#endif
  }
}
Beispiel #10
0
h2v2_merged_upsample_565D (j_decompress_ptr cinfo,
                           JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
                           JSAMPARRAY output_buf)
{
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  register int y, cred, cgreen, cblue;
  int cb, cr;
  register JSAMPROW outptr0, outptr1;
  JSAMPROW inptr00, inptr01, inptr1, inptr2;
  JDIMENSION col;
  /* copy these pointers into registers if possible */
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
  int * Crrtab = upsample->Cr_r_tab;
  int * Cbbtab = upsample->Cb_b_tab;
  INT32 * Crgtab = upsample->Cr_g_tab;
  INT32 * Cbgtab = upsample->Cb_g_tab;
  INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
  unsigned int r, g, b;
  INT32 rgb;
  SHIFT_TEMPS

  inptr00 = input_buf[0][in_row_group_ctr*2];
  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  inptr1 = input_buf[1][in_row_group_ctr];
  inptr2 = input_buf[2][in_row_group_ctr];
  outptr0 = output_buf[0];
  outptr1 = output_buf[1];

  /* Loop for each group of output pixels */
  for (col = cinfo->output_width >> 1; col > 0; col--) {
    /* Do the chroma part of the calculation */
    cb = GETJSAMPLE(*inptr1++);
    cr = GETJSAMPLE(*inptr2++);
    cred = Crrtab[cr];
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    cblue = Cbbtab[cb];

    /* Fetch 4 Y values and emit 4 pixels */
    y  = GETJSAMPLE(*inptr00++);
    r = range_limit[DITHER_565_R(y + cred, d0)];
    g = range_limit[DITHER_565_G(y + cgreen, d0)];
    b = range_limit[DITHER_565_B(y + cblue, d0)];
    d0 = DITHER_ROTATE(d0);
    rgb = PACK_SHORT_565(r, g, b);

    y  = GETJSAMPLE(*inptr00++);
    r = range_limit[DITHER_565_R(y + cred, d1)];
    g = range_limit[DITHER_565_G(y + cgreen, d1)];
    b = range_limit[DITHER_565_B(y + cblue, d1)];
    d1 = DITHER_ROTATE(d1);
    rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));

    WRITE_TWO_PIXELS(outptr0, rgb);
    outptr0 += 4;

    y  = GETJSAMPLE(*inptr01++);
    r = range_limit[DITHER_565_R(y + cred, d0)];
    g = range_limit[DITHER_565_G(y + cgreen, d0)];
    b = range_limit[DITHER_565_B(y + cblue, d0)];
    d0 = DITHER_ROTATE(d0);
    rgb = PACK_SHORT_565(r, g, b);

    y  = GETJSAMPLE(*inptr01++);
    r = range_limit[DITHER_565_R(y + cred, d1)];
    g = range_limit[DITHER_565_G(y + cgreen, d1)];
    b = range_limit[DITHER_565_B(y + cblue, d1)];
    d1 = DITHER_ROTATE(d1);
    rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));

    WRITE_TWO_PIXELS(outptr1, rgb);
    outptr1 += 4;
  }

  /* If image width is odd, do the last output column separately */
  if (cinfo->output_width & 1) {
    cb = GETJSAMPLE(*inptr1);
    cr = GETJSAMPLE(*inptr2);
    cred = Crrtab[cr];
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    cblue = Cbbtab[cb];

    y  = GETJSAMPLE(*inptr00);
    r = range_limit[DITHER_565_R(y + cred, d0)];
    g = range_limit[DITHER_565_G(y + cgreen, d0)];
    b = range_limit[DITHER_565_B(y + cblue, d0)];
    rgb = PACK_SHORT_565(r, g, b);
    *(INT16*)outptr0 = rgb;

    y  = GETJSAMPLE(*inptr01);
    r = range_limit[DITHER_565_R(y + cred, d1)];
    g = range_limit[DITHER_565_G(y + cgreen, d1)];
    b = range_limit[DITHER_565_B(y + cblue, d1)];
    rgb = PACK_SHORT_565(r, g, b);
    *(INT16*)outptr1 = rgb;
  }
}
Beispiel #11
0
METHODDEF void
h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
{
	JSAMPARRAY output_data = *output_data_ptr;
	register JSAMPROW inptr0, inptr1, outptr;
#if BITS_IN_JSAMPLE == 8
	register int thiscolsum, lastcolsum, nextcolsum;
#else
	register INT32 thiscolsum, lastcolsum, nextcolsum;
#endif
	register JDIMENSION colctr;
	int inrow, outrow, v;

	inrow = outrow = 0;

	while(outrow < cinfo->max_v_samp_factor)
	{
		for(v = 0; v < 2; v++)
		{
			/* inptr0 points to nearest input row, inptr1 points to next nearest */
			inptr0 = input_data[inrow];

			if(v == 0)      /* next nearest is row above */
			{
				inptr1 = input_data[inrow - 1];
			}
			else     /* next nearest is row below */
			{
				inptr1 = input_data[inrow + 1];
			}

			outptr = output_data[outrow++];

			/* Special case for first column */
			thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
			nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
			*outptr++ = (JSAMPLE)((thiscolsum * 4 + 8) >> 4);
			*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
			lastcolsum = thiscolsum;
			thiscolsum = nextcolsum;

			for(colctr = compptr->downsampled_width - 2; colctr > 0; colctr--)
			{
				/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
				/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
				nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
				*outptr++ = (JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4);
				*outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
				lastcolsum = thiscolsum;
				thiscolsum = nextcolsum;
			}

			/* Special case for last column */
			*outptr++ = (JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4);
			*outptr++ = (JSAMPLE)((thiscolsum * 4 + 7) >> 4);
		}

		inrow++;
	}
}
Beispiel #12
0
h2v1_merged_upsample_565 (j_decompress_ptr cinfo,
                          JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
                          JSAMPARRAY output_buf)
{
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  register int y, cred, cgreen, cblue;
  int cb, cr;
  register JSAMPROW outptr;
  JSAMPROW inptr0, inptr1, inptr2;
  JDIMENSION col;
  /* copy these pointers into registers if possible */
  register JSAMPLE * range_limit = cinfo->sample_range_limit;
  int * Crrtab = upsample->Cr_r_tab;
  int * Cbbtab = upsample->Cb_b_tab;
  INT32 * Crgtab = upsample->Cr_g_tab;
  INT32 * Cbgtab = upsample->Cb_g_tab;
  unsigned int r, g, b;
  INT32 rgb;
  SHIFT_TEMPS

  inptr0 = input_buf[0][in_row_group_ctr];
  inptr1 = input_buf[1][in_row_group_ctr];
  inptr2 = input_buf[2][in_row_group_ctr];
  outptr = output_buf[0];

  /* Loop for each pair of output pixels */
  for (col = cinfo->output_width >> 1; col > 0; col--) {
    /* Do the chroma part of the calculation */
    cb = GETJSAMPLE(*inptr1++);
    cr = GETJSAMPLE(*inptr2++);
    cred = Crrtab[cr];
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    cblue = Cbbtab[cb];

    /* Fetch 2 Y values and emit 2 pixels */
    y  = GETJSAMPLE(*inptr0++);
    r = range_limit[y + cred];
    g = range_limit[y + cgreen];
    b = range_limit[y + cblue];
    rgb = PACK_SHORT_565(r, g, b);

    y  = GETJSAMPLE(*inptr0++);
    r = range_limit[y + cred];
    g = range_limit[y + cgreen];
    b = range_limit[y + cblue];
    rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));

    WRITE_TWO_PIXELS(outptr, rgb);
    outptr += 4;
  }

  /* If image width is odd, do the last output column separately */
  if (cinfo->output_width & 1) {
    cb = GETJSAMPLE(*inptr1);
    cr = GETJSAMPLE(*inptr2);
    cred = Crrtab[cr];
    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    cblue = Cbbtab[cb];
    y  = GETJSAMPLE(*inptr0);
    r = range_limit[y + cred];
    g = range_limit[y + cgreen];
    b = range_limit[y + cblue];
    rgb = PACK_SHORT_565(r, g, b);
    *(INT16*)outptr = rgb;
   }
 }
Beispiel #13
0
write_colormap_buf (j_decompress_ptr cinfo, bmp_dest_ptr dest,
		int map_colors, int map_entry_size,char *buf)
{
  JSAMPARRAY colormap = cinfo->colormap;
  int num_colors = cinfo->actual_number_of_colors;
  FILE * outfile = dest->pub.output_file;
	JSAMPARRAY outbuffer= dest->pub.buffer;
  int i,k=54;

  if (colormap != NULL) {
    if (cinfo->out_color_components == 3) {
      /* Normal case with RGB colormap */
      for (i = 0; i < num_colors; i++) {
				
				*(buf+k)=GETJSAMPLE(colormap[2][i]);
				k++;
				*(buf+k)=GETJSAMPLE(colormap[1][i]);
				k++;
				*(buf+k)=GETJSAMPLE(colormap[0][i]);
				k++;
				if (map_entry_size == 4){
					//putc(0, outfile);
					*(buf+k)=0;
					k++;
				}
      }
    } else {
      /* Grayscale colormap (only happens with grayscale quantization) */
      for (i = 0; i < num_colors; i++) {
				
				*(buf+k)=GETJSAMPLE(colormap[0][i]);
				k++;
				*(buf+k)=GETJSAMPLE(colormap[0][i]);
				k++;
				*(buf+k)=GETJSAMPLE(colormap[0][i]);
				k++;
				if (map_entry_size == 4) {
					*(buf+k)=0;
					k++;
				}
      }
    }
  } else {
    /* If no colormap, must be grayscale data.  Generate a linear "map". */
    for (i = 0; i < 256; i++) {
						
			*(buf+k)=i;
			k++;
			*(buf+k)=i;
			k++;
			*(buf+k)=i;
			k++;
      if (map_entry_size == 4) {
				//putc(0, outfile);
				*(buf+k)=0;
				k++;
			}
    }
  }
  /* Pad colormap with zeros to ensure specified number of colormap entries */ 
  if (i > map_colors)
    ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i);
  for (; i < map_colors; i++) {
				
		*(buf+k)=0;
		k++;
		*(buf+k)=0;
		k++;
		*(buf+k)=0;
		k++;
    if (map_entry_size == 4) {
			//putc(0, outfile);
			*(buf+k)=0;
			k++;
		}
  }
}
Beispiel #14
0
quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
		     JSAMPARRAY output_buf, int num_rows)
/* General case, with ordered dithering */
{
  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
  register JSAMPROW input_ptr;
  register JSAMPROW output_ptr;
  JSAMPROW colorindex_ci;
  int * dither;			/* points to active row of dither matrix */
  int row_index, col_index;	/* current indexes into dither matrix */
  int nc = cinfo->out_color_components;
  int ci;
  int row;
  JDIMENSION col;
  JDIMENSION width = cinfo->output_width;

#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
  for (row = 0; row < num_rows; row++) {
    /* Initialize output values to 0 so can process components separately */
    jzero_far((void FAR *) output_buf[row],
	      (size_t) (width * SIZEOF(JSAMPLE)));
    row_index = cquantize->row_index;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
    for (ci = 0; ci < nc; ci++) {
      input_ptr = input_buf[row] + ci;
      output_ptr = output_buf[row];
      colorindex_ci = cquantize->colorindex[ci];
      dither = cquantize->odither[ci][row_index];
      col_index = 0;

#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
      for (col = width; col > 0; col--) {
	/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
	 * select output value, accumulate into output code for this pixel.
	 * Range-limiting need not be done explicitly, as we have extended
	 * the colorindex table to produce the right answers for out-of-range
	 * inputs.  The maximum dither is +- MAXJSAMPLE; this sets the
	 * required amount of padding.
	 */
	*output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
	input_ptr += nc;
	output_ptr++;
	col_index = (col_index + 1) & ODITHER_MASK;
      }
    }
    /* Advance row index for next row */
    row_index = (row_index + 1) & ODITHER_MASK;
    cquantize->row_index = row_index;
  }
}
Beispiel #15
0
jpeg_fdct_float (FAST_FLOAT * data, JSAMPARRAY sample_data, JDIMENSION start_col)
{
  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
  FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
  FAST_FLOAT *dataptr;
  JSAMPROW elemptr;
  int ctr;

  /* Pass 1: process rows. */

  dataptr = data;
  for (ctr = 0; ctr < DCTSIZE; ctr++) {
    elemptr = sample_data[ctr] + start_col;

    /* Load data into workspace */
    tmp0 = (FAST_FLOAT) (GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]));
    tmp7 = (FAST_FLOAT) (GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[7]));
    tmp1 = (FAST_FLOAT) (GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[6]));
    tmp6 = (FAST_FLOAT) (GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[6]));
    tmp2 = (FAST_FLOAT) (GETJSAMPLE(elemptr[2]) + GETJSAMPLE(elemptr[5]));
    tmp5 = (FAST_FLOAT) (GETJSAMPLE(elemptr[2]) - GETJSAMPLE(elemptr[5]));
    tmp3 = (FAST_FLOAT) (GETJSAMPLE(elemptr[3]) + GETJSAMPLE(elemptr[4]));
    tmp4 = (FAST_FLOAT) (GETJSAMPLE(elemptr[3]) - GETJSAMPLE(elemptr[4]));

    /* Even part */

    tmp10 = tmp0 + tmp3;	/* phase 2 */
    tmp13 = tmp0 - tmp3;
    tmp11 = tmp1 + tmp2;
    tmp12 = tmp1 - tmp2;

    /* Apply unsigned->signed conversion. */
    dataptr[0] = tmp10 + tmp11 - 8 * CENTERJSAMPLE; /* phase 3 */
    dataptr[4] = tmp10 - tmp11;

    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
    dataptr[2] = tmp13 + z1;	/* phase 5 */
    dataptr[6] = tmp13 - z1;

    /* Odd part */

    tmp10 = tmp4 + tmp5;	/* phase 2 */
    tmp11 = tmp5 + tmp6;
    tmp12 = tmp6 + tmp7;

    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */

    z11 = tmp7 + z3;		/* phase 5 */
    z13 = tmp7 - z3;

    dataptr[5] = z13 + z2;	/* phase 6 */
    dataptr[3] = z13 - z2;
    dataptr[1] = z11 + z4;
    dataptr[7] = z11 - z4;

    dataptr += DCTSIZE;		/* advance pointer to next row */
  }

  /* Pass 2: process columns. */

  dataptr = data;
  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];

    /* Even part */

    tmp10 = tmp0 + tmp3;	/* phase 2 */
    tmp13 = tmp0 - tmp3;
    tmp11 = tmp1 + tmp2;
    tmp12 = tmp1 - tmp2;

    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
    dataptr[DCTSIZE*4] = tmp10 - tmp11;

    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
    dataptr[DCTSIZE*6] = tmp13 - z1;

    /* Odd part */

    tmp10 = tmp4 + tmp5;	/* phase 2 */
    tmp11 = tmp5 + tmp6;
    tmp12 = tmp6 + tmp7;

    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */

    z11 = tmp7 + z3;		/* phase 5 */
    z13 = tmp7 - z3;

    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
    dataptr[DCTSIZE*3] = z13 - z2;
    dataptr[DCTSIZE*1] = z11 + z4;
    dataptr[DCTSIZE*7] = z11 - z4;

    dataptr++;			/* advance pointer to next column */
  }
}
Beispiel #16
0
METHODDEF void
h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
{
	int inrow, outrow;
	JDIMENSION colctr;
	JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
	register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
	INT32 membersum, neighsum, memberscale, neighscale;

	/* Expand input data enough to let all the output samples be generated
	 * by the standard loop.  Special-casing padded output would be more
	 * efficient.
	 */
	expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
	                  cinfo->image_width, output_cols * 2);

	/* We don't bother to form the individual "smoothed" input pixel values;
	 * we can directly compute the output which is the average of the four
	 * smoothed values.  Each of the four member pixels contributes a fraction
	 * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
	 * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
	 * output.  The four corner-adjacent neighbor pixels contribute a fraction
	 * SF to just one smoothed pixel, or SF/4 to the final output; while the
	 * eight edge-adjacent neighbors contribute SF to each of two smoothed
	 * pixels, or SF/2 overall.  In order to use integer arithmetic, these
	 * factors are scaled by 2^16 = 65536.
	 * Also recall that SF = smoothing_factor / 1024.
	 */

	memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
	neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */

	inrow = 0;

	for(outrow = 0; outrow < compptr->v_samp_factor; outrow++)
	{
		outptr = output_data[outrow];
		inptr0 = input_data[inrow];
		inptr1 = input_data[inrow + 1];
		above_ptr = input_data[inrow - 1];
		below_ptr = input_data[inrow + 2];

		/* Special case for first column: pretend column -1 is same as column 0 */
		membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
		            GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
		neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
		           GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
		           GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
		           GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
		neighsum += neighsum;
		neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
		            GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
		membersum = membersum * memberscale + neighsum * neighscale;
		*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
		inptr0 += 2;
		inptr1 += 2;
		above_ptr += 2;
		below_ptr += 2;

		for(colctr = output_cols - 2; colctr > 0; colctr--)
		{
			/* sum of pixels directly mapped to this output element */
			membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
			            GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
			/* sum of edge-neighbor pixels */
			neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
			           GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
			           GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
			           GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
			/* The edge-neighbors count twice as much as corner-neighbors */
			neighsum += neighsum;
			/* Add in the corner-neighbors */
			neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
			            GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
			/* form final output scaled up by 2^16 */
			membersum = membersum * memberscale + neighsum * neighscale;
			/* round, descale and output it */
			*outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
			inptr0 += 2;
			inptr1 += 2;
			above_ptr += 2;
			below_ptr += 2;
		}

		/* Special case for last column */
		membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
		            GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
		neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
		           GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
		           GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
		           GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
		neighsum += neighsum;
		neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
		            GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
		membersum = membersum * memberscale + neighsum * neighscale;
		*outptr = (JSAMPLE)((membersum + 32768) >> 16);

		inrow += 2;
	}
}
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
	     JDIMENSION start_row, JDIMENSION start_col,
	     JDIMENSION num_blocks)
/* This version is used for integer DCT implementations. */
{
  /* This routine is heavily used, so it's worth coding it tightly. */
  j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec;
  fdct_ptr fdct = (fdct_ptr) lossyc->fdct_private;
  forward_DCT_method_ptr do_dct = fdct->do_dct;
  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
  DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
  JDIMENSION bi;

  sample_data += start_row;	/* fold in the vertical offset once */

  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
    /* Load data into workspace, applying unsigned->signed conversion */
    { register DCTELEM *workspaceptr;
      register JSAMPROW elemptr;
      register int elemr;

      workspaceptr = workspace;
      for (elemr = 0; elemr < DCTSIZE; elemr++) {
	elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8		/* unroll the inner loop */
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
	{ register int elemc;
	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
	    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	  }
	}
#endif
      }
    }

    /* Perform the DCT */
    (*do_dct) (workspace);

    /* Quantize/descale the coefficients, and store into coef_blocks[] */
    { register DCTELEM temp, qval;
      register int i;
      register JCOEFPTR output_ptr = coef_blocks[bi];

      for (i = 0; i < DCTSIZE2; i++) {
	qval = divisors[i];
	temp = workspace[i];
	/* Divide the coefficient value by qval, ensuring proper rounding.
	 * Since C does not specify the direction of rounding for negative
	 * quotients, we have to force the dividend positive for portability.
	 *
	 * In most files, at least half of the output values will be zero
	 * (at default quantization settings, more like three-quarters...)
	 * so we should ensure that this case is fast.  On many machines,
	 * a comparison is enough cheaper than a divide to make a special test
	 * a win.  Since both inputs will be nonnegative, we need only test
	 * for a < b to discover whether a/b is 0.
	 * If your machine's division is fast enough, define FAST_DIVIDE.
	 */
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b)	a /= b
#else
#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
#endif
	if (temp < 0) {
	  temp = -temp;
	  temp += qval>>1;	/* for rounding */
	  DIVIDE_BY(temp, qval);
	  temp = -temp;
	} else {
	  temp += qval>>1;	/* for rounding */
	  DIVIDE_BY(temp, qval);
	}
	output_ptr[i] = (JCOEF) temp;
      }
    }
Beispiel #18
0
static int bmJpegRememberScanline( JSAMPARRAY			pixel_data,
				struct jpeg_decompress_struct * cinfo	)
    {
    BmJpegInputSource *		bjis= (BmJpegInputSource *)cinfo->src;

    unsigned char *		to;
    register JSAMPROW		ptr0;
    long			col;

    switch( cinfo->out_color_space )
	{
	case JCS_GRAYSCALE:
	    switch( bjis->bjisBd.bdBitsPerSample )
		{
		case 8:
		    to= bjis->bjisBitmapBuffer+
			bjis->bjisBd.bdBytesPerRow*
					    (bjis->bjisRowsReceived++);

		    ptr0 = pixel_data[0];

		    for ( col = 0; col < cinfo->image_width; col++ )
			{ *(to++)= GETJSAMPLE(*(ptr0++));	}
		    break;
		default:
		    LDEB(bjis->bjisBd.bdBitsPerSample); 
		    return -1;
		}
	    break;

	case JCS_RGB:
	    switch( bjis->bjisBd.bdBitsPerSample )
		{
		case 8:
		    to= bjis->bjisBitmapBuffer+
			bjis->bjisBd.bdBytesPerRow*
					    (bjis->bjisRowsReceived++);

		    ptr0 = pixel_data[0];

		    for ( col = 0; col < cinfo->image_width; col++ )
			{
			*(to++)= GETJSAMPLE(*(ptr0++));	/* red */
			*(to++)= GETJSAMPLE(*(ptr0++));	/* green */
			*(to++)= GETJSAMPLE(*(ptr0++));	/* blue */
			}
		    break;
		default:
		    LDEB(bjis->bjisBd.bdBitsPerSample); 
		    return -1;
		}
	    break;

	case JCS_UNKNOWN:
	case JCS_YCbCr:
	case JCS_YCCK:
	case JCS_CMYK:
	    LDEB(cinfo->out_color_space);
	    return -1;
	    break;

	default:
	    LDEB(cinfo->out_color_space);
	    return -1;
	    break;
	}

    return 0;
    }