mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	find * -type f "-(" -name "*.bdf" -o -name "*.c" -o -name "*.h" -o -name "*.py" -o -name "*.rst" -o -name "*.txt" "-)" -exec sed -e "s/[[:space:]]*$//" -i {} \;
		
	
			
		
			
				
	
	
		
			256 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			256 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * The Python Imaging Library
 | |
|  * $Id$
 | |
|  *
 | |
|  * imaging access objects
 | |
|  *
 | |
|  * Copyright (c) Fredrik Lundh 2009.
 | |
|  *
 | |
|  * See the README file for information on usage and redistribution.
 | |
|  */
 | |
| 
 | |
| 
 | |
| #include "Imaging.h"
 | |
| 
 | |
| /* use Tests/make_hash.py to calculate these values */
 | |
| #define ACCESS_TABLE_SIZE 21
 | |
| #define ACCESS_TABLE_HASH 30197
 | |
| 
 | |
| static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE];
 | |
| 
 | |
| static inline UINT32
 | |
| hash(const char* mode)
 | |
| {
 | |
|     UINT32 i = ACCESS_TABLE_HASH;
 | |
|     while (*mode)
 | |
|         i = ((i<<5) + i) ^ (UINT8) *mode++;
 | |
|     return i % ACCESS_TABLE_SIZE;
 | |
| }
 | |
| 
 | |
| static ImagingAccess
 | |
| add_item(const char* mode)
 | |
| {
 | |
|     UINT32 i = hash(mode);
 | |
|     /* printf("hash %s => %d\n", mode, i); */
 | |
|     if (access_table[i].mode) {
 | |
|         fprintf(stderr, "AccessInit: hash collision: %d for both %s and %s\n",
 | |
|                 i, mode, access_table[i].mode);
 | |
|         exit(1);
 | |
|     }
 | |
|     access_table[i].mode = mode;
 | |
|     return &access_table[i];
 | |
| }
 | |
| 
 | |
| /* fetch pointer to pixel line */
 | |
| 
 | |
| static void*
 | |
| line_8(Imaging im, int x, int y)
 | |
| {
 | |
|     return &im->image8[y][x];
 | |
| }
 | |
| 
 | |
| static void*
 | |
| line_16(Imaging im, int x, int y)
 | |
| {
 | |
|     return &im->image8[y][x+x];
 | |
| }
 | |
| 
 | |
| static void*
 | |
| line_32(Imaging im, int x, int y)
 | |
| {
 | |
|     return &im->image32[y][x];
 | |
| }
 | |
| 
 | |
| /* fetch individual pixel */
 | |
| 
 | |
| static void
 | |
| get_pixel(Imaging im, int x, int y, void* color)
 | |
| {
 | |
|     char* out = color;
 | |
| 
 | |
|     /* generic pixel access*/
 | |
| 
 | |
|     if (im->image8) {
 | |
|         out[0] = im->image8[y][x];
 | |
|     } else {
 | |
|         UINT8* p = (UINT8*) &im->image32[y][x];
 | |
|         if (im->type == IMAGING_TYPE_UINT8 && im->bands == 2) {
 | |
|             out[0] = p[0];
 | |
|             out[1] = p[3];
 | |
|             return;
 | |
|         }
 | |
|         memcpy(out, p, im->pixelsize);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| get_pixel_8(Imaging im, int x, int y, void* color)
 | |
| {
 | |
|     char* out = color;
 | |
|     out[0] = im->image8[y][x];
 | |
| }
 | |
| 
 | |
| static void
 | |
| get_pixel_16L(Imaging im, int x, int y, void* color)
 | |
| {
 | |
|     UINT8* in = (UINT8*) &im->image[y][x+x];
 | |
|     INT16* out = color;
 | |
| #ifdef WORDS_BIGENDIAN
 | |
|     out[0] = in[0] + (in[1]<<8);
 | |
| #else
 | |
|     out[0] = *(INT16*) in;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static void
 | |
| get_pixel_16B(Imaging im, int x, int y, void* color)
 | |
| {
 | |
|     UINT8* in = (UINT8*) &im->image[y][x+x];
 | |
|     INT16* out = color;
 | |
| #ifdef WORDS_BIGENDIAN
 | |
|     out[0] = *(INT16*) in;
 | |
| #else
 | |
|     out[0] = in[1] + (in[0]<<8);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static void
 | |
| get_pixel_32(Imaging im, int x, int y, void* color)
 | |
| {
 | |
|     INT32* out = color;
 | |
|     out[0] = im->image32[y][x];
 | |
| }
 | |
| 
 | |
| static void
 | |
| get_pixel_32L(Imaging im, int x, int y, void* color)
 | |
| {
 | |
|     UINT8* in = (UINT8*) &im->image[y][x*4];
 | |
|     INT32* out = color;
 | |
| #ifdef WORDS_BIGENDIAN
 | |
|     out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24);
 | |
| #else
 | |
|     out[0] = *(INT32*) in;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static void
 | |
| get_pixel_32B(Imaging im, int x, int y, void* color)
 | |
| {
 | |
|     UINT8* in = (UINT8*) &im->image[y][x*4];
 | |
|     INT32* out = color;
 | |
| #ifdef WORDS_BIGENDIAN
 | |
|     out[0] = *(INT32*) in;
 | |
| #else
 | |
|     out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /* store individual pixel */
 | |
| 
 | |
| static void
 | |
| put_pixel(Imaging im, int x, int y, const void* color)
 | |
| {
 | |
|     if (im->image8)
 | |
|         im->image8[y][x] = *((UINT8*) color);
 | |
|     else
 | |
|         im->image32[y][x] = *((INT32*) color);
 | |
| }
 | |
| 
 | |
| static void
 | |
| put_pixel_8(Imaging im, int x, int y, const void* color)
 | |
| {
 | |
|     im->image8[y][x] = *((UINT8*) color);
 | |
| }
 | |
| 
 | |
| static void
 | |
| put_pixel_16L(Imaging im, int x, int y, const void* color)
 | |
| {
 | |
|     const char* in = color;
 | |
|     UINT8* out = (UINT8*) &im->image8[y][x+x];
 | |
|     out[0] = in[0];
 | |
|     out[1] = in[1];
 | |
| }
 | |
| 
 | |
| static void
 | |
| put_pixel_16B(Imaging im, int x, int y, const void* color)
 | |
| {
 | |
|     const char* in = color;
 | |
|     UINT8* out = (UINT8*) &im->image8[y][x+x];
 | |
|     out[0] = in[1];
 | |
|     out[1] = in[0];
 | |
| }
 | |
| 
 | |
| static void
 | |
| put_pixel_32L(Imaging im, int x, int y, const void* color)
 | |
| {
 | |
|     const char* in = color;
 | |
|     UINT8* out = (UINT8*) &im->image8[y][x*4];
 | |
|     out[0] = in[0];
 | |
|     out[1] = in[1];
 | |
|     out[2] = in[2];
 | |
|     out[3] = in[3];
 | |
| }
 | |
| 
 | |
| static void
 | |
| put_pixel_32B(Imaging im, int x, int y, const void* color)
 | |
| {
 | |
|     const char* in = color;
 | |
|     UINT8* out = (UINT8*) &im->image8[y][x*4];
 | |
|     out[0] = in[3];
 | |
|     out[1] = in[2];
 | |
|     out[2] = in[1];
 | |
|     out[3] = in[0];
 | |
| }
 | |
| 
 | |
| static void
 | |
| put_pixel_32(Imaging im, int x, int y, const void* color)
 | |
| {
 | |
|     im->image32[y][x] = *((INT32*) color);
 | |
| }
 | |
| 
 | |
| void
 | |
| ImagingAccessInit()
 | |
| {
 | |
| #define ADD(mode_, line_, get_pixel_, put_pixel_)       \
 | |
|     { ImagingAccess access = add_item(mode_);           \
 | |
|         access->line = line_;                           \
 | |
|         access->get_pixel = get_pixel_;                 \
 | |
|         access->put_pixel = put_pixel_;                 \
 | |
|     }
 | |
| 
 | |
|     /* populate access table */
 | |
|     ADD("1", line_8, get_pixel_8, put_pixel_8);
 | |
|     ADD("L", line_8, get_pixel_8, put_pixel_8);
 | |
|     ADD("LA", line_32, get_pixel, put_pixel);
 | |
|     ADD("I", line_32, get_pixel_32, put_pixel_32);
 | |
|     ADD("I;16", line_16, get_pixel_16L, put_pixel_16L);
 | |
|     ADD("I;16L", line_16, get_pixel_16L, put_pixel_16L);
 | |
|     ADD("I;16B", line_16, get_pixel_16B, put_pixel_16B);
 | |
|     ADD("I;32L", line_32, get_pixel_32L, put_pixel_32L);
 | |
|     ADD("I;32B", line_32, get_pixel_32B, put_pixel_32B);
 | |
|     ADD("F", line_32, get_pixel_32, put_pixel_32);
 | |
|     ADD("P", line_8, get_pixel_8, put_pixel_8);
 | |
|     ADD("PA", line_32, get_pixel, put_pixel);
 | |
|     ADD("RGB", line_32, get_pixel_32, put_pixel_32);
 | |
|     ADD("RGBA", line_32, get_pixel_32, put_pixel_32);
 | |
|     ADD("RGBa", line_32, get_pixel_32, put_pixel_32);
 | |
|     ADD("RGBX", line_32, get_pixel_32, put_pixel_32);
 | |
|     ADD("CMYK", line_32, get_pixel_32, put_pixel_32);
 | |
|     ADD("YCbCr", line_32, get_pixel_32, put_pixel_32);
 | |
| }
 | |
| 
 | |
| ImagingAccess
 | |
| ImagingAccessNew(Imaging im)
 | |
| {
 | |
|     ImagingAccess access = &access_table[hash(im->mode)];
 | |
|     if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0)
 | |
|         return NULL;
 | |
|     return access;
 | |
| }
 | |
| 
 | |
| void
 | |
| _ImagingAccessDelete(Imaging im, ImagingAccess access)
 | |
| {
 | |
| 
 | |
| }
 |