示例#1
0
文件: gray.c 项目: mmerickel/Simpl
int simpl_gray_to_image(SimplImage **image,
                        const SimplGrayImage *gray_img,
                        const SimplGrayToColorMethods method)
{
	size_t i, size;
	int result;
	
	if (gray_img && gray_img->image && gray_img->width && gray_img->height) {
		result = simpl_image(image, gray_img->width, gray_img->height);
		if (result!=SIMPL_OK) return result;
		
		size = gray_img->width * gray_img->height;
		
		switch (method) {
		case GRAY_TO_COLOR_RED:
			for (i=0; i<size; ++i) {
				(*image)->image[i].red = gray_img->image[i];
			}
			break;
			
		case GRAY_TO_COLOR_GREEN:
			for (i=0; i<size; ++i) {
				(*image)->image[i].green = gray_img->image[i];
			}
			break;
			
		case GRAY_TO_COLOR_BLUE:
			for (i=0; i<size; ++i) {
				(*image)->image[i].blue = gray_img->image[i];
			}
			break;
			
		case GRAY_TO_COLOR_ALPHA:
			simpl_alpha_create(*image);
			for (i=0; i<size; ++i) {
				(*image)->alpha[i] = gray_img->image[i];
			}
			break;
			
		case GRAY_TO_ALL:
		default:
			for (i=0; i<size; ++i) {
				(*image)->image[i].red   = gray_img->image[i];
				(*image)->image[i].green = gray_img->image[i];
				(*image)->image[i].blue  = gray_img->image[i];
			}
			break;
		}
	}  else return SIMPL_BAD_PARAMS;
	
	return SIMPL_OK;
}
示例#2
0
文件: image.c 项目: componica/Simpl
int simpl_image_copy(SimplImage **dest_img,
                     const SimplImage *src_img)
{
    int result;
    
    if (src_img && src_img->image && src_img->width && src_img->height) {
        if (*dest_img==src_img) return SIMPL_OK;
        
        result = simpl_image(dest_img, src_img->width, src_img->height);
        if (result!=SIMPL_OK) return result;
        
        memcpy((*dest_img)->image, src_img->image, src_img->width * src_img->height * sizeof(SimplColorPixel));
        
        if (src_img->alpha) {
            simpl_alpha_create(*dest_img);
            memcpy((*dest_img)->alpha, src_img->alpha, src_img->width * src_img->height * sizeof(SimplPixel));
        }
    } else return SIMPL_BAD_PARAMS;
    
    return SIMPL_OK;
}
示例#3
0
int simpl_image_load_jpg(SimplImage **image,
                         SimplInStream istream)
{
    struct jpeg_decompress_struct cinfo;
    LibJpegErrorMgr jerr;
    
    JDIMENSION width, height, row_stride, i;
    JOCTET *row_data = NULL;
    
    int y, u, v;
    SimplColorPixel *ptr, *row_ptr;
    int out = SIMPL_INTERNAL;
    
    /* Allocate and initialize JPEG decompression object. */
    cinfo.err = jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit = JpegLoadErrorExit;
    
    /* Establish the setjmp return context for JpegLoadErrorExit to use. */
    if (setjmp(jerr.setjmp_buffer)) {
        goto error;
    }
    
    /* Now we can initialize the JPEG decompression object and file. */
    jpeg_create_decompress(&cinfo);
    JpegMyReader(&cinfo, istream);
    
    /* Read file parameters with jpeg_read_header(). */
    jpeg_read_header(&cinfo, TRUE);
    
    /* Start decompresser. */
    jpeg_start_decompress(&cinfo);
    
    /* Allocate the image and line buffer. */
    width  = cinfo.image_width;
    height = cinfo.image_height;
    row_stride = cinfo.output_width * cinfo.output_components;
    
    row_data = (JOCTET *)malloc(cinfo.image_width*4*sizeof(JOCTET));
    if (!row_data) {
        out = SIMPL_NOMEM;
        goto error;
    }
    
    out = simpl_image(image, width, height);
    if (out != SIMPL_OK) goto error;
    
    /* Extract the image. */
    switch (cinfo.out_color_space) {
    case JCS_GRAYSCALE:
        row_ptr = (*image)->image;
        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, &row_data, 1);
            
            ptr = row_ptr;
            for (i=0; i<row_stride; i++) {
                ptr->red = ptr->green = ptr->blue = row_data[i];
                ptr++;
            }
            row_ptr += width;
        }
        break;
    
    case JCS_RGB:
        row_ptr = (*image)->image;
        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, &row_data, 1);
            
            ptr = row_ptr;
            for (i=0; i<row_stride; i+=3) {
                ptr->red   = row_data[i];
                ptr->green = row_data[i+1];
                ptr->blue  = row_data[i+2];
                ptr++;
            }
            row_ptr += width;
        }
        break;
    
    case JCS_YCbCr:
        row_ptr = (*image)->image;
        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, &row_data, 1);
            
            ptr = row_ptr;
            for (i=0; i<row_stride; i+=3) {
                y = row_data[i];
                u = row_data[i+1];
                v = row_data[i+2];
                ptr->red   = y + ((360*(v-128))>>8);
                ptr->green = y - ((88*(u-128)+183*(v-128))>>8);
                ptr->blue  = y + ((455 * (u-128))>>8);
                ptr++;
            }
            row_ptr += width;
        }
        break;
    
    case JCS_CMYK:
        row_ptr = (*image)->image;
        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, &row_data, 1);
            
            ptr = row_ptr;
            for (i=0; i<row_stride; i+=4) {
                y = 255 - row_data[i+3];
                ptr->red   = y - ((row_data[i]*y)>>8);
                ptr->green = y - ((row_data[i+1]*y)>>8);
                ptr->blue  = y - ((row_data[i+2]*y)>>8);
                ptr++;
            }
            row_ptr += width;
        }
        break;
    
    default:
        simpl_image_clear(*image, simpl_color(0,0,0));
        break;
    }
    
error:
    if (row_data) free((void *)row_data);
    jpeg_destroy_decompress(&cinfo);
    return out;
}
示例#4
0
int simpl_image_load_png(SimplImage **image,
                         SimplInStream istream)
{
	png_structp png_ptr;
	png_infop info_ptr;
	png_byte color_type, bitdepth, *row_data=NULL;
	png_bytep* row_ptrs=NULL;
	
	png_uint_32 i, j, width, height, row_size;
	
	SimplColorPixel *iptr;
	SimplPixel *aptr;
	
	int out = SIMPL_INTERNAL;
	
	/* Create a read struct. */
	if (!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) {
		return SIMPL_INTERNAL;
	}
	
	/* Create an info struct. */
	if (!(info_ptr = png_create_info_struct(png_ptr))) {
		goto error;
	}
	
	/* Handle libpng errors with a magic setjmp. */
	if (setjmp(png_jmpbuf(png_ptr))) {
		goto error;
	}
	
	/* Set the stream-based data source. */
	png_set_read_fn(png_ptr, istream, StreamReadData);
	
	/* Read the info chunk. */
	png_read_info(png_ptr, info_ptr);
	
	/* Get the dimensions and color information. */
	width = png_get_image_width(png_ptr, info_ptr);
	height = png_get_image_height(png_ptr, info_ptr);
	bitdepth = png_get_bit_depth(png_ptr, info_ptr);
	color_type = png_get_color_type(png_ptr, info_ptr);
	
	/* If palette, low bit depth gray, transparent w/o alpha, or 16 bit, fix it. */
	if (color_type == PNG_COLOR_TYPE_PALETTE) {
		png_set_palette_to_rgb(png_ptr);
		color_type = png_get_color_type(png_ptr, info_ptr);
	} else if (color_type == PNG_COLOR_TYPE_GRAY) {
		if (bitdepth<8) png_set_expand_gray_1_2_4_to_8(png_ptr);
		bitdepth = 8;
	}
	
	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
		png_set_tRNS_to_alpha(png_ptr);
		color_type = png_get_color_type(png_ptr, info_ptr);
	}
	
	png_set_strip_16(png_ptr);
	
	/* Either allocate a row, or load the entire image into a buffer. This is
	 * because single row access uses less memory but doesn't work for
	 * interlaced PNGs.
	 */
	row_size = png_get_rowbytes(png_ptr, info_ptr);
	if (png_get_interlace_type(png_ptr, info_ptr)==PNG_INTERLACE_NONE) {
		row_data = (png_byte *)malloc(sizeof(png_byte) * row_size);
		if (!row_data) {
			out = SIMPL_NOMEM;
			goto error;
		}
	} else {
		row_ptrs = (png_bytep*)calloc(height, sizeof(png_bytep));
		if (!row_ptrs) {
			out = SIMPL_NOMEM;
			goto error;
		}
		
		for (j=0; j<height; ++j) {
			row_ptrs[j] = (png_byte *)malloc(sizeof(png_byte) * row_size);
			if (!row_ptrs[j]) {
				out = SIMPL_NOMEM;
				goto error;
			}
		}
		
		png_read_image(png_ptr, row_ptrs);
	}
		
	/* Allocate an image of the specified size. */
	out = simpl_image(image, width, height);
	if (out != SIMPL_OK) goto error;
		
	/* Store the decoded image into our format. */
	if (color_type == PNG_COLOR_TYPE_RGB) {
		for (j=0; j<height; j++) {
			if (row_ptrs) row_data = row_ptrs[j];
			else png_read_row(png_ptr, row_data, NULL);
			
			iptr = (*image)->image + j * width;
			for (i=0; i<3*width; i+=3) {
				iptr->red   = row_data[i];
				iptr->green = row_data[i+1];
				iptr->blue  = row_data[i+2];
				iptr++;
			}
		}
	} else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
		simpl_alpha_create(*image);
		for (j=0; j<height; j++) {
			if (row_ptrs) row_data = row_ptrs[j];
			else png_read_row(png_ptr, row_data, NULL);
			
			iptr = (*image)->image + j * width;
			aptr = (*image)->alpha + j * width;
			for (i=0; i<4*width; i+=4) {
				iptr->red   = row_data[i];
				iptr->green = row_data[i+1];
				iptr->blue  = row_data[i+2];
				iptr++;
			
				*aptr++ = row_data[i+3];
			}
		}
	} else if (color_type == PNG_COLOR_TYPE_GRAY) {
		for (j=0; j<height; j++) {
			if (row_ptrs) row_data = row_ptrs[j];
			else png_read_row(png_ptr, row_data, NULL);
			
			iptr = (*image)->image + j * width;
			for (i=0; i<width; i++) {
				iptr->red   = row_data[i];
				iptr->green = row_data[i];
				iptr->blue  = row_data[i];
				iptr++;
			}
		}
	} else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
		simpl_alpha_create(*image);
		for (j=0; j<height; j++) {
			if (row_ptrs) row_data = row_ptrs[j];
			else png_read_row(png_ptr, row_data, NULL);
			
			iptr = (*image)->image + j * width;
			aptr = (*image)->alpha + j * width;
			for (i=0; i<2*width; i+=2) {
				iptr->red   = row_data[i];
				iptr->green = row_data[i];
				iptr->blue  = row_data[i];
				iptr++;
			
				*aptr++ = row_data[i+1];
			}
		}
	} else goto error;
	
error:
	if (row_ptrs) {
		for (j=0; j<height; ++j) {
			if (row_ptrs[j]) free((void *)row_ptrs[j]);
		}
		
		free((void *)row_ptrs);
	} else {
		if (row_data) free((void *)row_data);
	}
	
	png_destroy_read_struct(&png_ptr, &info_ptr, 0);
	return out;
}