Ejemplo n.º 1
0
int simpl_gray_copy(SimplGrayImage **dest_img,
                    const SimplGrayImage *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_gray(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(SimplPixel));
	} else return SIMPL_BAD_PARAMS;
	
	return SIMPL_OK;
}
Ejemplo n.º 2
0
int simpl_gray_load_png(SimplGrayImage **image,
                        SimplInStream istream,
                        const SimplColorToGrayMethods method,
                        const SimplPixel bk_value)
{
	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, x, width, height, row_size;
	
	SimplColorPixel *pixels=NULL;
	SimplPixel *iptr, *alpha=NULL;
	
	int value, 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_gray(image, width, height);
	if (out != SIMPL_OK) goto error;
	
	/* Decode the image line by line. */
	if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
		pixels = (SimplColorPixel *)malloc(sizeof(SimplColorPixel) * width);
		if (!pixels) {
			out = SIMPL_NOMEM;
			goto error;
		}
		
		alpha = (SimplPixel *)malloc(sizeof(SimplPixel) * width);
		if (!alpha) {
			out = SIMPL_NOMEM;
			goto error;
		}
		memset(alpha, 255, width);
		
		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;
			
			if (color_type==PNG_COLOR_TYPE_RGB) {
				for (x=i=0; x<width; ++x, i+=3) {
					pixels[x].red   = row_data[i];
					pixels[x].green = row_data[i+1];
					pixels[x].blue  = row_data[i+2];
				}
			} else {
				for (x=i=0; x<width; ++x, i+=4) {
					pixels[x].red   = row_data[i];
					pixels[x].green = row_data[i+1];
					pixels[x].blue  = row_data[i+2];
					alpha[x]        = row_data[i+3];
				}
			}
			
			switch(method) {
			case COLOR_TO_GRAY_RED:
				for (i=0; i<width; ++i) iptr[i] = pixels[i].red;
				break;
				
			case COLOR_TO_GRAY_GREEN:
				for (i=0; i<width; ++i) iptr[i] = pixels[i].green;
				break;
				
			case COLOR_TO_GRAY_BLUE:
				for (i=0; i<width; ++i) iptr[i] = pixels[i].blue;
				break;
				
			case COLOR_TO_GRAY_ALPHA:
				for (i=0; i<width; ++i) iptr[i] = alpha[i];
				break;
				
			case COLOR_TO_GRAY_CIE:
				if (color_type==PNG_COLOR_TYPE_RGB_ALPHA) {
					for (i=0; i<width; ++i) {
						value = (6969*pixels[i].red + 23434*pixels[i].green + 2365*pixels[i].blue)>>15;
						value = (alpha[i]*value + (255-alpha[i])*bk_value) / 255;
						iptr[i] = (value>255)?255:value;
					}
				} else {
					for (i=0; i<width; ++i) {
						value = (6969*pixels[i].red + 23434*pixels[i].green + 2365*pixels[i].blue)>>15;
						iptr[i] = (value>255)?255:value;
					}
				}
				break;
				
			case COLOR_TO_GRAY_MEAN:
			default:
				if (color_type==PNG_COLOR_TYPE_RGB_ALPHA) {
					for (i=0; i<width; ++i) {
						value = (pixels[i].red + pixels[i].green + pixels[i].blue)/3;
						value = (alpha[i]*value + (255-alpha[i])*bk_value) / 255;
						iptr[i] = (value>255)?255:value;
					}
				} else {
					for (i=0; i<width; ++i) {
						value = (pixels[i].red + pixels[i].green + pixels[i].blue)/3;
						iptr[i] = (value>255)?255:value;
					}
				}
				break;
			}
		}
Ejemplo n.º 3
0
int simpl_gray_load_jpg(SimplGrayImage **image,
                        SimplInStream istream,
                        const SimplColorToGrayMethods method,
                        const SimplPixel bk_value)
{
    struct jpeg_decompress_struct cinfo;
    LibJpegErrorMgr jerr;
    
    JDIMENSION width, height, row_stride, i;
    JOCTET *row_data = NULL;
    
    int y, u, v;
    SimplColorPixel *row=NULL, *row_ptr;
    SimplPixel *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;
    }
    
    row = (SimplColorPixel *)malloc(width * sizeof(SimplColorPixel));
    if (!row) {
        out = SIMPL_NOMEM;
        goto error;
    }
    
    out = simpl_gray(image, width, height);
    if (out != SIMPL_OK) goto error;
    ptr = (*image)->image;
    
    /* Extract the image. */
    if (cinfo.out_color_space==JCS_GRAYSCALE) {
        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, &row_data, 1);
            for (i=0; i<row_stride; i++) ptr[i] = row_data[i];
            ptr += width;
        }
    } else if (cinfo.out_color_space==JCS_RGB || cinfo.out_color_space==JCS_YCbCr || cinfo.out_color_space==JCS_CMYK) {
        while (cinfo.output_scanline < cinfo.output_height) {
            jpeg_read_scanlines(&cinfo, &row_data, 1);
            row_ptr = row;
            
            if (cinfo.out_color_space==JCS_RGB) {
                for (i=0; i<row_stride; i+=3) {
                    row_ptr->red   = row_data[i];
                    row_ptr->green = row_data[i+1];
                    row_ptr->blue  = row_data[i+2];
                    ++row_ptr;
                }
            } else if (cinfo.out_color_space==JCS_YCbCr) {
                for (i=0; i<row_stride; i+=3) {
                    y = row_data[i];
                    u = row_data[i+1];
                    v = row_data[i+2];
                    row_ptr->red   = y + ((360*(v-128))>>8);
                    row_ptr->green = y - ((88*(u-128)+183*(v-128))>>8);
                    row_ptr->blue  = y + ((455 * (u-128))>>8);
                    ++row_ptr;
                }
            } else {
                for (i=0; i<row_stride; i+=4) {
                    y = 255 - row_data[i+3];
                    row_ptr->red   = y - ((row_data[i]*y)>>8);
                    row_ptr->green = y - ((row_data[i+1]*y)>>8);
                    row_ptr->blue  = y - ((row_data[i+2]*y)>>8);
                    ++row_ptr;
                }
            }
            
            switch(method) {
            case COLOR_TO_GRAY_RED:
                for (i=0; i<width; ++i) ptr[i] = row[i].red;
                break;
                
            case COLOR_TO_GRAY_GREEN:
                for (i=0; i<width; ++i) ptr[i] = row[i].green;
                break;
                
            case COLOR_TO_GRAY_BLUE:
                for (i=0; i<width; ++i) ptr[i] = row[i].blue;
                break;
                
            case COLOR_TO_GRAY_ALPHA:
                for (i=0; i<width; ++i) ptr[i] = 255;
                break;
                
            case COLOR_TO_GRAY_CIE:
                for (i=0; i<width; ++i) {
                    y = (6969*row[i].red + 23434*row[i].green + 2365*row[i].blue)>>15;
                    ptr[i] = (y>255)?255:y;
                }
                break;
                
            case COLOR_TO_GRAY_MEAN:
            default:
                for (i=0; i<width; ++i) {
                    y = (row[i].red + row[i].green + row[i].blue)/3;
                    ptr[i] = (y>255)?255:y;
                }
                break;
            }
            
            ptr += width;
        }
    } else {
Ejemplo n.º 4
0
int simpl_image_to_gray(SimplGrayImage **gray_img,
                        const SimplImage *image,
                        const SimplColorToGrayMethods method,
                        const SimplPixel bk_value)
{
    size_t i, size;
    int result, value;
    SimplPixel *out;
    
    if (image && image->image && image->width && image->height) {
        result = simpl_gray(gray_img, image->width, image->height);
        if (result!=SIMPL_OK) return result;
        
        size = image->width * image->height;
        out = (*gray_img)->image;
        
        switch (method) {
        case COLOR_TO_GRAY_RED:
            for (i=0; i<size; ++i) {
                out[i] = image->image[i].red;
            }
            break;
            
        case COLOR_TO_GRAY_GREEN:
            for (i=0; i<size; ++i) {
                out[i] = image->image[i].green;
            }
            break;
            
        case COLOR_TO_GRAY_BLUE:
            for (i=0; i<size; ++i) {
                out[i] = image->image[i].blue;
            }
            break;
            
        case COLOR_TO_GRAY_ALPHA:
            if (image->alpha) {
                for (i=0; i<size; ++i) {
                    out[i] = image->alpha[i];
                }
            } else {
                for (i=0; i<size; ++i) {
                    out[i] = 255;
                }
            }
            break;
            
        case COLOR_TO_GRAY_CIE:
            if (image->alpha) {
                for (i=0; i<size; ++i) {
                    value = (6969*image->image[i].red + 23434*image->image[i].green + 2365*image->image[i].blue)>>15;
                    value = (image->alpha[i]*value + (255-image->alpha[i])*bk_value) / 255;
                    out[i] = (value>255)?255:value;
                }
            } else {
                for (i=0; i<size; ++i) {
                    value = (6969*image->image[i].red + 23434*image->image[i].green + 2365*image->image[i].blue)>>15;
                    out[i] = (value>255)?255:value;
                }
            }
            break;
            
        case COLOR_TO_GRAY_MEAN:
        default:
            if (image->alpha) {
                for (i=0; i<size; ++i) {
                    value = (image->image[i].red + image->image[i].green + image->image[i].blue) / 3;
                    value = (image->alpha[i]*value + (255-image->alpha[i])*bk_value) / 255;
                    out[i] = (value>255)?255:value;
                }
            } else {
                for (i=0; i<size; ++i) {
                    value = (image->image[i].red + image->image[i].green + image->image[i].blue) / 3;
                    out[i] = (value>255)?255:value;
                }
            }
            break;
        }