Esempio n. 1
0
h2v2_upsample(
	j_decompress_ptr cinfo, jpeg_component_info*, JSAMPARRAY input_data,
	JSAMPARRAY* output_data_ptr)
{
	JSAMPARRAY output_data = *output_data_ptr;
	JSAMPROW inptr, outptr;
	JSAMPLE invalue;
	JSAMPROW outend;
	int inrow, outrow;

	inrow = outrow = 0;
	while (outrow < cinfo->max_v_samp_factor)
	{
		inptr = input_data[inrow];
		outptr = output_data[outrow];
		outend = outptr + cinfo->output_width;
		while (outptr < outend)
		{
			invalue = *inptr++; /* don't need GETJSAMPLE() here */
			*outptr++ = invalue;
			*outptr++ = invalue;
		}
		jcopy_sample_rows(
			output_data, outrow, output_data, outrow + 1, 1,
			cinfo->output_width);
		inrow++;
		outrow += 2;
	}
}
Esempio n. 2
0
void grayscale_convert (j_decompress_ptr cinfo,
		   JSAMPIMAGE input_buf, JDIMENSION input_row,
		   JSAMPARRAY output_buf, int num_rows)
{
  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
		    num_rows, cinfo->output_width);
}
Esempio n. 3
0
expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
                    int input_rows, int output_rows)
{
    register int row;

    for (row = input_rows; row < output_rows; row++) {
        jcopy_sample_rows(image_data, input_rows-1, image_data, row,
                          1, num_cols);
    }
}
Esempio n. 4
0
fullsize_downsample( j_compress_ptr cinfo, jpeg_component_info *compptr,
					 JSAMPARRAY input_data, JSAMPARRAY output_data )
{
	/* Copy the data */
	jcopy_sample_rows( input_data, 0, output_data, 0,
					   cinfo->max_v_samp_factor, cinfo->image_width );
	/* Edge-expand */
	expand_right_edge( output_data, cinfo->max_v_samp_factor, cinfo->image_width,
					   compptr->width_in_blocks * compptr->DCT_h_scaled_size );
}
Esempio n. 5
0
LOCAL void
duplicate_row (JSAMPARRAY image_data,
	       long num_cols, int source_row, int num_rows)
/* Duplicate the source_row at source_row+1 .. source_row+num_rows */
/* This happens only at the bottom of the image, */
/* so it needn't be super-efficient */
{
  register int row;

  for (row = 1; row <= num_rows; row++) {
    jcopy_sample_rows(image_data, source_row, image_data, source_row + row,
		      1, num_cols);
  }
}
Esempio n. 6
0
merged_2v_upsample (j_decompress_ptr cinfo,
                    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
                    JDIMENSION in_row_groups_avail,
                    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
                    JDIMENSION out_rows_avail)
/* 2:1 vertical sampling case: may need a spare row. */
{
  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  JSAMPROW work_ptrs[2];
  JDIMENSION num_rows;          /* number of rows returned to caller */

  if (upsample->spare_full) {
    /* If we have a spare row saved from a previous cycle, just return it. */
    JDIMENSION size = upsample->out_row_width;
    if (cinfo->out_color_space == JCS_RGB565)
      size = cinfo->output_width * 2;
    jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
                      1, size);
    num_rows = 1;
    upsample->spare_full = FALSE;
  } else {
    /* Figure number of rows to return to caller. */
    num_rows = 2;
    /* Not more than the distance to the end of the image. */
    if (num_rows > upsample->rows_to_go)
      num_rows = upsample->rows_to_go;
    /* And not more than what the client can accept: */
    out_rows_avail -= *out_row_ctr;
    if (num_rows > out_rows_avail)
      num_rows = out_rows_avail;
    /* Create output pointer array for upsampler. */
    work_ptrs[0] = output_buf[*out_row_ctr];
    if (num_rows > 1) {
      work_ptrs[1] = output_buf[*out_row_ctr + 1];
    } else {
      work_ptrs[1] = upsample->spare_row;
      upsample->spare_full = TRUE;
    }
    /* Now do the upsampling. */
    (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
  }

  /* Adjust counts */
  *out_row_ctr += num_rows;
  upsample->rows_to_go -= num_rows;
  /* When the buffer is emptied, declare this input row group consumed */
  if (! upsample->spare_full)
    (*in_row_group_ctr)++;
}
Esempio n. 7
0
METHODDEF void
int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
             JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
{
	my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
	JSAMPARRAY output_data = *output_data_ptr;
	register JSAMPROW inptr, outptr;
	register JSAMPLE invalue;
	register int h;
	JSAMPROW outend;
	int h_expand, v_expand;
	int inrow, outrow;

	h_expand = upsample->h_expand[compptr->component_index];
	v_expand = upsample->v_expand[compptr->component_index];

	inrow = outrow = 0;

	while(outrow < cinfo->max_v_samp_factor)
	{
		/* Generate one output row with proper horizontal expansion */
		inptr = input_data[inrow];
		outptr = output_data[outrow];
		outend = outptr + cinfo->output_width;

		while(outptr < outend)
		{
			invalue = *inptr++; /* don't need GETJSAMPLE() here */

			for(h = h_expand; h > 0; h--)
			{
				*outptr++ = invalue;
			}
		}

		/* Generate any additional output rows by duplicating the first one */
		if(v_expand > 1)
		{
			jcopy_sample_rows(output_data, outrow, output_data, outrow + 1,
			                  v_expand - 1, cinfo->output_width);
		}

		inrow++;
		outrow += v_expand;
	}
}
Esempio n. 8
0
edge_expand (compress_info_ptr cinfo,
	     long input_cols, int input_rows,
	     long output_cols, int output_rows,
	     JSAMPIMAGE image_data)
#endif	/* XIE_SUPPORTED */
{
  /* Expand horizontally */
  if (input_cols < output_cols) {
    register JSAMPROW ptr;
    register JSAMPLE pixval;
    register long count;
    register int row;
    short ci;
    long numcols = output_cols - input_cols;

    for (ci = 0; ci < cinfo->num_components; ci++) {
      for (row = 0; row < input_rows; row++) {
	ptr = image_data[ci][row] + (input_cols-1);
	pixval = GETJSAMPLE(*ptr++);
	for (count = numcols; count > 0; count--)
	  *ptr++ = pixval;
      }
    }
  }

  /* Expand vertically */
  /* This happens only once at the bottom of the image, */
  /* so it needn't be super-efficient */
  if (input_rows < output_rows) {
    register int row;
    short ci;
    JSAMPARRAY this_component;

    for (ci = 0; ci < cinfo->num_components; ci++) {
      this_component = image_data[ci];
      for (row = input_rows; row < output_rows; row++) {
	jcopy_sample_rows(this_component, input_rows-1, this_component, row,
			  1, output_cols);
      }
    }
  }
}
Esempio n. 9
0
pre_process_context (j_compress_ptr cinfo,
                     JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
                     JDIMENSION in_rows_avail,
                     JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
                     JDIMENSION out_row_groups_avail)
{
    my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
    int numrows, ci;
    int buf_height = cinfo->max_v_samp_factor * 3;
    JDIMENSION inrows;

    while (*out_row_group_ctr < out_row_groups_avail) {
        if (*in_row_ctr < in_rows_avail) {
            /* Do color conversion to fill the conversion buffer. */
            inrows = in_rows_avail - *in_row_ctr;
            numrows = prep->next_buf_stop - prep->next_buf_row;
            numrows = (int) MIN((JDIMENSION) numrows, inrows);
            (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
                                               prep->color_buf,
                                               (JDIMENSION) prep->next_buf_row,
                                               numrows);
            /* Pad at top of image, if first time through */
            if (prep->rows_to_go == cinfo->image_height) {
                for (ci = 0; ci < cinfo->num_components; ci++) {
                    int row;
                    for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
                        jcopy_sample_rows(prep->color_buf[ci], 0,
                                          prep->color_buf[ci], -row,
                                          1, cinfo->image_width);
                    }
                }
            }
            *in_row_ctr += numrows;
            prep->next_buf_row += numrows;
            prep->rows_to_go -= numrows;
        } else {
            /* Return for more data, unless we are at the bottom of the image. */
            if (prep->rows_to_go != 0)
                break;
            /* When at bottom of image, pad to fill the conversion buffer. */
            if (prep->next_buf_row < prep->next_buf_stop) {
                for (ci = 0; ci < cinfo->num_components; ci++) {
                    expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
                                       prep->next_buf_row, prep->next_buf_stop);
                }
                prep->next_buf_row = prep->next_buf_stop;
            }
        }
        /* If we've gotten enough data, downsample a row group. */
        if (prep->next_buf_row == prep->next_buf_stop) {
            (*cinfo->downsample->downsample) (cinfo,
                                              prep->color_buf,
                                              (JDIMENSION) prep->this_row_group,
                                              output_buf, *out_row_group_ctr);
            (*out_row_group_ctr)++;
            /* Advance pointers with wraparound as necessary. */
            prep->this_row_group += cinfo->max_v_samp_factor;
            if (prep->this_row_group >= buf_height)
                prep->this_row_group = 0;
            if (prep->next_buf_row >= buf_height)
                prep->next_buf_row = 0;
            prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
        }
    }
}
Esempio n. 10
0
METHODDEF void
pre_process_context( j_compress_ptr cinfo,
                     JSAMPARRAY input_buf, JDIMENSION * in_row_ctr,
                     JDIMENSION in_rows_avail,
                     JSAMPIMAGE output_buf, JDIMENSION * out_row_group_ctr,
                     JDIMENSION out_row_groups_avail ) {
    my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
    int numrows, ci;
    int buf_height = cinfo->max_v_samp_factor * 3;
    JDIMENSION inrows;
    jpeg_component_info * compptr;

    while ( *out_row_group_ctr < out_row_groups_avail ) {
        if ( *in_row_ctr < in_rows_avail ) {
            /* Do color conversion to fill the conversion buffer. */
            inrows = in_rows_avail - *in_row_ctr;
            numrows = prep->next_buf_stop - prep->next_buf_row;
            numrows = (int) MIN( (JDIMENSION) numrows, inrows );
            ( *cinfo->cconvert->color_convert )( cinfo, input_buf + *in_row_ctr,
                                                 prep->color_buf,
                                                 (JDIMENSION) prep->next_buf_row,
                                                 numrows );
            /* Pad at top of image, if first time through */
            if ( prep->rows_to_go == cinfo->image_height ) {
                for ( ci = 0; ci < cinfo->num_components; ci++ ) {
                    int row;
                    for ( row = 1; row <= cinfo->max_v_samp_factor; row++ ) {
                        jcopy_sample_rows( prep->color_buf[ci], 0,
                                           prep->color_buf[ci], -row,
                                           1, cinfo->image_width );
                    }
                }
            }
            *in_row_ctr += numrows;
            prep->next_buf_row += numrows;
            prep->rows_to_go -= numrows;
        } else {
            /* Return for more data, unless we are at the bottom of the image. */
            if ( prep->rows_to_go != 0 ) {
                break;
            }
        }
        /* If at bottom of image, pad to fill the conversion buffer. */
        if ( ( prep->rows_to_go == 0 ) &&
            ( prep->next_buf_row < prep->next_buf_stop ) ) {
            for ( ci = 0; ci < cinfo->num_components; ci++ ) {
                expand_bottom_edge( prep->color_buf[ci], cinfo->image_width,
                                    prep->next_buf_row, prep->next_buf_stop );
            }
            prep->next_buf_row = prep->next_buf_stop;
        }
        /* If we've gotten enough data, downsample a row group. */
        if ( prep->next_buf_row == prep->next_buf_stop ) {
            ( *cinfo->downsample->downsample )( cinfo,
                                                prep->color_buf,
                                                (JDIMENSION) prep->this_row_group,
                                                output_buf, *out_row_group_ctr );
            ( *out_row_group_ctr )++;
            /* Advance pointers with wraparound as necessary. */
            prep->this_row_group += cinfo->max_v_samp_factor;
            if ( prep->this_row_group >= buf_height ) {
                prep->this_row_group = 0;
            }
            if ( prep->next_buf_row >= buf_height ) {
                prep->next_buf_row = 0;
            }
            prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
        }
        /* If at bottom of image, pad the output to a full iMCU height.
         * Note we assume the caller is providing a one-iMCU-height output buffer!
         */
        if ( ( prep->rows_to_go == 0 ) &&
            ( *out_row_group_ctr < out_row_groups_avail ) ) {
            for ( ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
                  ci++, compptr++ ) {
                expand_bottom_edge( output_buf[ci],
                                   compptr->width_in_blocks * DCTSIZE,
                                   (int) ( *out_row_group_ctr * compptr->v_samp_factor ),
                                   (int) ( out_row_groups_avail * compptr->v_samp_factor ) );
            }
            *out_row_group_ctr = out_row_groups_avail;
            break;      /* can exit outer loop without test */
        }
    }
}
Esempio n. 11
0
DLLEXPORT int DLLCALL tjCompress(tjhandle h,
	unsigned char *srcbuf, int width, int pitch, int height, int ps,
	unsigned char *dstbuf, unsigned long *size,
	int jpegsub, int qual, int flags)
{
	int i, retval=0;  JSAMPROW *row_pointer=NULL;
	JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS];
	JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS];
	JSAMPROW *outbuf[MAX_COMPONENTS];

	checkhandle(h);

	for(i=0; i<MAX_COMPONENTS; i++)
	{
		tmpbuf[i]=NULL;  _tmpbuf[i]=NULL;
		tmpbuf2[i]=NULL;  _tmpbuf2[i]=NULL;  outbuf[i]=NULL;
	}

	if(srcbuf==NULL || width<=0 || pitch<0 || height<=0
		|| dstbuf==NULL || size==NULL
		|| jpegsub<0 || jpegsub>=NUMSUBOPT || qual<0 || qual>100)
		_throw("Invalid argument in tjCompress()");
	if(ps!=3 && ps!=4 && ps!=1)
		_throw("This compressor can only handle 24-bit and 32-bit RGB or 8-bit grayscale input");
	if(!j->initc) _throw("Instance has not been initialized for compression");

	if(pitch==0) pitch=width*ps;

	j->cinfo.image_width = width;
	j->cinfo.image_height = height;
	j->cinfo.input_components = ps;

	if(ps==1) j->cinfo.in_color_space = JCS_GRAYSCALE;
	#if JCS_EXTENSIONS==1
	else j->cinfo.in_color_space = JCS_EXT_RGB;
	if(ps==3 && (flags&TJ_BGR))
		j->cinfo.in_color_space = JCS_EXT_BGR;
	else if(ps==4 && !(flags&TJ_BGR) && !(flags&TJ_ALPHAFIRST))
		j->cinfo.in_color_space = JCS_EXT_RGBX;
	else if(ps==4 && (flags&TJ_BGR) && !(flags&TJ_ALPHAFIRST))
		j->cinfo.in_color_space = JCS_EXT_BGRX;
	else if(ps==4 && (flags&TJ_BGR) && (flags&TJ_ALPHAFIRST))
		j->cinfo.in_color_space = JCS_EXT_XBGR;
	else if(ps==4 && !(flags&TJ_BGR) && (flags&TJ_ALPHAFIRST))
		j->cinfo.in_color_space = JCS_EXT_XRGB;
	#else
	#error "TurboJPEG requires JPEG colorspace extensions"
	#endif

	if(flags&TJ_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
	else if(flags&TJ_FORCESSE) putenv("JSIMD_FORCESSE=1");
	else if(flags&TJ_FORCESSE2) putenv("JSIMD_FORCESSE2=1");

	if(setjmp(j->jerr.jb))
	{  // this will execute if LIBJPEG has an error
		retval=-1;
		goto bailout;
	}

	jpeg_set_defaults(&j->cinfo);

	jpeg_set_quality(&j->cinfo, qual, TRUE);
	if(jpegsub==TJ_GRAYSCALE)
		jpeg_set_colorspace(&j->cinfo, JCS_GRAYSCALE);
	else
		jpeg_set_colorspace(&j->cinfo, JCS_YCbCr);
	if(qual>=96) j->cinfo.dct_method=JDCT_ISLOW;
	else j->cinfo.dct_method=JDCT_FASTEST;

	j->cinfo.comp_info[0].h_samp_factor=hsampfactor[jpegsub];
	j->cinfo.comp_info[1].h_samp_factor=1;
	j->cinfo.comp_info[2].h_samp_factor=1;
	j->cinfo.comp_info[0].v_samp_factor=vsampfactor[jpegsub];
	j->cinfo.comp_info[1].v_samp_factor=1;
	j->cinfo.comp_info[2].v_samp_factor=1;

	j->jdms.next_output_byte = dstbuf;
	j->jdms.free_in_buffer = TJBUFSIZE(j->cinfo.image_width, j->cinfo.image_height);

	jpeg_start_compress(&j->cinfo, TRUE);
	if(flags&TJ_YUV)
	{
		j_compress_ptr cinfo=&j->cinfo;
		int row;
		int pw=PAD(width, cinfo->max_h_samp_factor);
		int ph=PAD(height, cinfo->max_v_samp_factor);
		int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS];
		jpeg_component_info *compptr;
		JSAMPLE *ptr=dstbuf;  unsigned long yuvsize=0;

		if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL)
			_throw("Memory allocation failed in tjCompress()");
		for(i=0; i<height; i++)
		{
			if(flags&TJ_BOTTOMUP) row_pointer[i]= &srcbuf[(height-i-1)*pitch];
			else row_pointer[i]= &srcbuf[i*pitch];
		}
		if(height<ph)
			for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1];

		for(i=0; i<cinfo->num_components; i++)
		{
			compptr=&cinfo->comp_info[i];
			_tmpbuf[i]=(JSAMPLE *)malloc(
				PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE)
					/compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16);
			if(!_tmpbuf[i]) _throw("Memory allocation failure");
			tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor);
			if(!tmpbuf[i]) _throw("Memory allocation failure");
			for(row=0; row<cinfo->max_v_samp_factor; row++)
			{
				unsigned char *_tmpbuf_aligned=
					(unsigned char *)PAD((size_t)_tmpbuf[i], 16);
				tmpbuf[i][row]=&_tmpbuf_aligned[
					PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE)
						/compptr->h_samp_factor, 16) * row];
			}
			_tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16)
				* compptr->v_samp_factor + 16);
			if(!_tmpbuf2[i]) _throw("Memory allocation failure");
			tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor);
			if(!tmpbuf2[i]) _throw("Memory allocation failure");
			for(row=0; row<compptr->v_samp_factor; row++)
			{
				unsigned char *_tmpbuf2_aligned=
					(unsigned char *)PAD((size_t)_tmpbuf2[i], 16);
				tmpbuf2[i][row]=&_tmpbuf2_aligned[
					PAD(compptr->width_in_blocks*DCTSIZE, 16) * row];
			}
			cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor;
			ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor;
			outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]);
			if(!outbuf[i]) _throw("Memory allocation failure");
			for(row=0; row<ch[i]; row++)
			{
				outbuf[i][row]=ptr;
				ptr+=PAD(cw[i], 4);
			}
		}
		yuvsize=(unsigned long)(ptr-dstbuf);

		for(row=0; row<ph; row+=cinfo->max_v_samp_factor)
		{
			(*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf,
				0, cinfo->max_v_samp_factor);
			(cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0);
			for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components;
				i++, compptr++)
				jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i],
					row*compptr->v_samp_factor/cinfo->max_v_samp_factor,
					compptr->v_samp_factor, cw[i]);
		}
		*size=yuvsize;
		cinfo->next_scanline+=height;
	}
	else
	{
		if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL)
			_throw("Memory allocation failed in tjCompress()");
		for(i=0; i<height; i++)
		{
			if(flags&TJ_BOTTOMUP) row_pointer[i]= &srcbuf[(height-i-1)*pitch];
			else row_pointer[i]= &srcbuf[i*pitch];
		}
		while(j->cinfo.next_scanline<j->cinfo.image_height)
		{
			jpeg_write_scanlines(&j->cinfo, &row_pointer[j->cinfo.next_scanline],
				j->cinfo.image_height-j->cinfo.next_scanline);
		}
	}
	jpeg_finish_compress(&j->cinfo);
	if(!(flags&TJ_YUV))
		*size=TJBUFSIZE(j->cinfo.image_width, j->cinfo.image_height)
			-(unsigned long)(j->jdms.free_in_buffer);

	bailout:
	if(j->cinfo.global_state>CSTATE_START) jpeg_abort_compress(&j->cinfo);
	if(row_pointer) free(row_pointer);
	for(i=0; i<MAX_COMPONENTS; i++)
	{
		if(tmpbuf[i]!=NULL) free(tmpbuf[i]);
		if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]);
		if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]);
		if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]);
		if(outbuf[i]!=NULL) free(outbuf[i]);
	}
	return retval;
}