Exemple #1
0
/* Yuk! Have to malloc enough space for the whole image. Interlaced PNG
 * is not really suitable for large objects ...
 */
static int
png2vips_interlace( Read *read )
{
	const int rowbytes = IM_IMAGE_SIZEOF_LINE( read->out );
	int y;

	if( !(read->row_pointer = IM_ARRAY( NULL, 
		read->pInfo->height, png_bytep )) )
		return( -1 );
	if( !(read->data = (png_bytep) im_malloc( NULL,
		read->pInfo->height * rowbytes ))  )
		return( -1 );

	for( y = 0; y < (int) read->pInfo->height; y++ )
		read->row_pointer[y] = read->data + y * rowbytes;
	if( im_outcheck( read->out ) || 
		im_setupout( read->out ) || 
		setjmp( read->pPng->jmpbuf ) ) 
		return( -1 );

	png_read_image( read->pPng, read->row_pointer );

	for( y = 0; y < (int) read->pInfo->height; y++ )
		if( im_writeline( y, read->out, read->row_pointer[y] ) )
			return( -1 );

	return( 0 );
}
double *im_dvector(int nl, int nh)
{
	double *v;

	v = (double *)im_malloc(NULL,(unsigned)(nh - nl + 1) * sizeof(double));
	if (v == NULL)
		return(NULL);
	else
		return(v-nl);
}
float *im_fvector(int nl, int nh)
{
	float *v;

	v = (float *)im_malloc(NULL,(unsigned)(nh - nl + 1) * sizeof(float));
	if (v == NULL)
		return(NULL);
	else
		return(v-nl);
}
Exemple #4
0
static int
attach_thumbnail( IMAGE *im, ExifData *ed )
{
	if( ed->size > 0 ) {
		char *thumb_copy;

		thumb_copy = im_malloc( NULL, ed->size );      
		memcpy( thumb_copy, ed->data, ed->size );

		if( im_meta_set_blob( im, "jpeg-thumbnail-data", 
			(im_callback_fn) im_free, thumb_copy, ed->size ) ) {
			im_free( thumb_copy );
			return( -1 );
		}
	}

	return( 0 );
}
Exemple #5
0
/* Decode base64 back to binary in a malloc'd buffer. NULL on error.
 */
unsigned char *
im__b64_decode( const char *buffer, size_t *data_length )
{
	const size_t buffer_length = strlen( buffer );

	/* Worst case.
	 */
	const size_t output_data_length = buffer_length * 3 / 4;

	unsigned char *data;
	unsigned char *p;
	unsigned int bits;
	int nbits;
	size_t i;

	if( output_data_length > 1024 * 1024 ) {
		/* We shouldn't really be used for large amounts of data.
		 */
		im_error( "im__b64_decode", "%s", _( "too much data" ) );
		return( NULL );
	}

	if( !(data = im_malloc( NULL, output_data_length )) )
		return( NULL );

	p = data;
	bits = 0;
	nbits = 0;

	for( i = 0; i < buffer_length; i++ ) {
		unsigned int val;

		if( (val = b64_index[(int) buffer[i]]) != XX ) {
			bits <<= 6;
			bits |= val;
			nbits += 6;

			if( nbits >= 8 ) {
				*p++ = (bits >> (nbits - 8)) & 0xff;
				nbits -= 8;
			}
		}
Exemple #6
0
/**
 * im_fav4:
 * @in: array of 4 input #IMAGE s
 * @out: output #IMAGE
 *
 * Average four identical images. 
 *
 * Deprecated.
*/
int
im_fav4( IMAGE **in, IMAGE *out)
{
	PEL *result, *buffer, *p1, *p2, *p3, *p4;
	int x,y;
	int linebytes, PICY;

/* check IMAGEs parameters 
*/
if(im_iocheck(in[1], out)) return(-1);

/* BYTE images only!
*/
if( (in[0]->BandFmt != IM_BANDFMT_CHAR) &&  (in[0]->BandFmt != IM_BANDFMT_UCHAR)) return(-1);

if ( im_cp_desc(out, in[1]) == -1)   /* copy image descriptors */
      return(-1);
if ( im_setupout(out) == -1)
      return(-1);

linebytes = in[0]->Xsize * in[0]->Bands;
PICY = in[0]->Ysize;
buffer = (PEL*)im_malloc(NULL,linebytes);
memset(buffer, 0, linebytes);

	p1 = (PEL*)in[0]->data;
	p2 = (PEL*)in[1]->data;
	p3 = (PEL*)in[2]->data;
	p4 = (PEL*)in[3]->data;

for (y = 0; y < PICY; y++)
	{
	result = buffer;
	/* average 4 pels with rounding, for whole line*/
	for (x = 0; x < linebytes; x++) {
		*result++ = (PEL)((int)((int)*p1++ + (int)*p2++ + (int)*p3++ + (int)*p4++ +2) >> 2);
		}
	im_writeline(y,out, buffer);
	}
im_free(buffer);
return(0);
}
Exemple #7
0
Draw *
im__draw_init( Draw *draw, IMAGE *im, PEL *ink )
{
	if( im_rwcheck( im ) )
		return( NULL );

	draw->im = im;
	draw->ink = NULL;

	draw->lsize = IM_IMAGE_SIZEOF_LINE( im );
	draw->psize = IM_IMAGE_SIZEOF_PEL( im );
	draw->noclip = FALSE;

	if( ink ) {
		if( !(draw->ink = (PEL *) im_malloc( NULL, draw->psize )) ) 
			return( NULL );
		memcpy( draw->ink, ink, draw->psize );
	}

	return( draw );
}
Exemple #8
0
/* Noninterlaced images can be read without needing enough RAM for the whole
 * image.
 */
static int
png2vips_noninterlace( Read *read )
{
	const int rowbytes = IM_IMAGE_SIZEOF_LINE( read->out );
	int y;

	if( !(read->data = (png_bytep) im_malloc( NULL, rowbytes ))  )
		return( -1 );
	if( im_outcheck( read->out ) || 
		im_setupout( read->out ) || 
		setjmp( read->pPng->jmpbuf ) ) 
		return( -1 );

	for( y = 0; y < (int) read->pInfo->height; y++ ) {
		png_read_row( read->pPng, read->data, NULL );

		if( im_writeline( y, read->out, read->data ) )
			return( -1 );
	}

	return( 0 );
}
Exemple #9
0
static int
buffer_move( im_buffer_t *buffer, Rect *area )
{
	IMAGE *im = buffer->im;
	size_t new_bsize;

	g_assert( buffer->ref_count == 1 );

	buffer->area = *area;
	im_buffer_undone( buffer );
	g_assert( !buffer->done );

	new_bsize = (size_t) IM_IMAGE_SIZEOF_PEL( im ) * 
		area->width * area->height;
	if( buffer->bsize < new_bsize ) {
		buffer->bsize = new_bsize;
		IM_FREE( buffer->buf );
		if( !(buffer->buf = im_malloc( NULL, buffer->bsize )) ) 
			return( -1 );
	}

	return( 0 );
}
Exemple #10
0
/* Make a new buffer.
 */
im_buffer_t *
im_buffer_new( IMAGE *im, Rect *area )
{
	im_buffer_t *buffer;

	if( !(buffer = IM_NEW( NULL, im_buffer_t )) )
		return( NULL );

	buffer->ref_count = 1;
	buffer->im = im;
	buffer->area = *area;
	buffer->done = FALSE;
	buffer->cache = NULL;
	buffer->bsize = (size_t) IM_IMAGE_SIZEOF_PEL( im ) * 
		area->width * area->height;
	if( !(buffer->buf = im_malloc( NULL, buffer->bsize )) ) {
		im_buffer_unref( buffer );
		return( NULL );
	}

#ifdef DEBUG
	printf( "** im_buffer_new: left = %d, top = %d, "
		"width = %d, height = %d (%p)\n",
		buffer->area.left, buffer->area.top, 
		buffer->area.width, buffer->area.height, 
		buffer );
#endif /*DEBUG*/

#ifdef DEBUG
	g_mutex_lock( im__global_lock );
	im__buffers_all = g_slist_prepend( im__buffers_all, buffer );
	printf( "%d buffers in vips\n", g_slist_length( im__buffers_all ) );
	g_mutex_unlock( im__global_lock );
#endif /*DEBUG*/

	return( buffer );
}
Exemple #11
0
/* Output to a malloc'd buffer, NULL on error. Try to be simple and reliable,
 * rather than quick.
 */
char *
im__b64_encode( const unsigned char *data, size_t data_length )
{
	/* Worst case: 1.333 chars per byte, plus 10% for extra carriage 
	 * returns and stuff. And the \n\0 at the end.
	 */
	const size_t output_data_length = data_length * 44 / 30 + 2;

	char *buffer;
	char *p;
	size_t i;
	int cursor;

	if( data_length <= 0 ) {
		im_error( "im__b64_encode", "%s", _( "too little data" ) );
		return( NULL );
	}
	if( output_data_length > 1024 * 1024 ) {
		/* We shouldn't really be used for large amounts of data.
		 */
		im_error( "im__b64_encode", "%s", _( "too much data" ) );
		return( NULL );
	}
	if( !(buffer = im_malloc( NULL, output_data_length )) ) 
		return( NULL );

	p = buffer;
	*p++ = '\n';
	cursor = 0;

	for( i = 0; i < data_length; i += 3 ) {
		size_t remaining = data_length - i;
		int bits;

		bits = read24( data + i, remaining );
		encode24( p, bits, remaining * 8 );
		p += 4;
		cursor += 4;

		if( cursor >= 76 ) {
			*p++ = '\n';
			cursor = 0;
		}
	}
	if( cursor > 0 ) 
		*p++ = '\n';
	*p++ = '\0';

#ifdef DEBUG
{
	unsigned int total;

	/* Calculate a very simple checksum for debugging.
	 */
	for( total = 0, i = 0; i < data_length; i++ )
		total += data[i];

	printf( "im__b64_encode: length = %d, checksum 0x%x\n", 
		data_length, total & 0xffff );
}
#endif /*DEBUG*/

	return( buffer );
}
Exemple #12
0
/* Read a cinfo to a VIPS image. Set invert_pels if the pixel reader needs to
 * do 255-pel.
 */
static int
read_jpeg_header( struct jpeg_decompress_struct *cinfo, 
	IMAGE *out, gboolean *invert_pels, int shrink )
{
	jpeg_saved_marker_ptr p;
	int type;

	/* Capture app2 sections here for assembly.
	 */
	void *app2_data[MAX_APP2_SECTIONS] = { 0 };
	int app2_data_length[MAX_APP2_SECTIONS] = { 0 };
	int data_length;
	int i;

	/* Read JPEG header. libjpeg will set out_color_space sanely for us 
	 * for YUV YCCK etc.
	 */
	jpeg_read_header( cinfo, TRUE );
	cinfo->scale_denom = shrink;
	cinfo->scale_num = 1;
	jpeg_calc_output_dimensions( cinfo );

	*invert_pels = FALSE;
	switch( cinfo->out_color_space ) {
	case JCS_GRAYSCALE:
		type = IM_TYPE_B_W;
		break;

	case JCS_CMYK:
		type = IM_TYPE_CMYK;
		/* Photoshop writes CMYK JPEG inverted :-( Maybe this is a
		 * way to spot photoshop CMYK JPGs.
		 */
		if( cinfo->saw_Adobe_marker ) 
			*invert_pels = TRUE;
		break;

	case JCS_RGB:
	default:
		type = IM_TYPE_sRGB;
		break;
	}

	/* Set VIPS header.
	 */
	im_initdesc( out,
		 cinfo->output_width, cinfo->output_height,
		 cinfo->output_components,
		 IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, type,
		 1.0, 1.0, 0, 0 );

	/* Interlaced jpegs need lots of memory to read, so our caller needs
	 * to know.
	 */
	(void) im_meta_set_int( out, "jpeg-multiscan", 
		jpeg_has_multiple_scans( cinfo ) );

	/* Look for EXIF and ICC profile.
	 */
	for( p = cinfo->marker_list; p; p = p->next ) {
		switch( p->marker ) {
		case JPEG_APP0 + 1:
			/* EXIF data.
			 */
#ifdef DEBUG
			printf( "read_jpeg_header: seen %d bytes of APP1\n",
				p->data_length );
#endif /*DEBUG*/
			if( read_exif( out, p->data, p->data_length ) )
				return( -1 );
			break;

		case JPEG_APP0 + 2:
			/* ICC profile.
			 */
#ifdef DEBUG
			printf( "read_jpeg_header: seen %d bytes of APP2\n",
				p->data_length );
#endif /*DEBUG*/

			if( p->data_length > 14 &&
				im_isprefix( "ICC_PROFILE", 
					(char *) p->data ) ) {
				/* cur_marker numbers from 1, according to
				 * spec.
				 */
				int cur_marker = p->data[12] - 1;

				if( cur_marker >= 0 &&
					cur_marker < MAX_APP2_SECTIONS ) {
					app2_data[cur_marker] = p->data + 14;
					app2_data_length[cur_marker] = 
						p->data_length - 14;
				}
			}
			break;

		default:
#ifdef DEBUG
			printf( "read_jpeg_header: seen %d bytes of data\n",
				p->data_length );
#endif /*DEBUG*/
			break;
		}
	}

	/* Assemble ICC sections.
	 */
	data_length = 0;
	for( i = 0; i < MAX_APP2_SECTIONS && app2_data[i]; i++ )
		data_length += app2_data_length[i];
	if( data_length ) {
		unsigned char *data;
		int p;

#ifdef DEBUG
		printf( "read_jpeg_header: assembled %d byte ICC profile\n",
			data_length );
#endif /*DEBUG*/

		if( !(data = im_malloc( NULL, data_length )) ) 
			return( -1 );

		p = 0;
		for( i = 0; i < MAX_APP2_SECTIONS && app2_data[i]; i++ ) {
			memcpy( data + p, app2_data[i], app2_data_length[i] );
			p += app2_data_length[i];
		}

		if( im_meta_set_blob( out, IM_META_ICC_NAME, 
			(im_callback_fn) im_free, data, data_length ) ) {
			im_free( data );
			return( -1 );
		}
	}

	return( 0 );
}
Exemple #13
0
static int
read_exif( IMAGE *im, void *data, int data_length )
{
	char *data_copy;

	/* Horrifyingly, some JPEGs have several APP1 sections. We must only
	 * use the first one that starts "Exif.."
	 */
	if( ((char *) data)[0] != 'E' ||
		((char *) data)[1] != 'x' ||
		((char *) data)[2] != 'i' ||
		((char *) data)[3] != 'f' )
		return( 0 );
	if( im_header_get_typeof( im, IM_META_EXIF_NAME ) ) 
		return( 0 );

	/* Always attach a copy of the unparsed exif data.
	 */
	if( !(data_copy = im_malloc( NULL, data_length )) )
		return( -1 );
	memcpy( data_copy, data, data_length );
	if( im_meta_set_blob( im, IM_META_EXIF_NAME, 
		(im_callback_fn) im_free, data_copy, data_length ) ) {
		im_free( data_copy );
		return( -1 );
	}

#ifdef HAVE_EXIF
{
	ExifData *ed;

	if( !(ed = exif_data_new_from_data( data, data_length )) )
		return( -1 );

	if( ed->size > 0 ) {
#ifdef DEBUG_VERBOSE
		show_tags( ed );
		show_values( ed );
#endif /*DEBUG_VERBOSE*/

		/* Attach informational fields for what we find.

			FIXME ... better to have this in the UI layer?

			Or we could attach non-human-readable tags here (int, 
			double etc) and then move the human stuff to the UI 
			layer?

		 */
		exif_data_foreach_content( ed, 
			(ExifDataForeachContentFunc) attach_exif_content, im );

		/* Look for resolution fields and use them to set the VIPS 
		 * xres/yres fields.
		 */
		set_vips_resolution( im, ed );

		attach_thumbnail( im, ed );
	}

	exif_data_free( ed );
}
#endif /*HAVE_EXIF*/

	return( 0 );
}