IMG_pcx.c
changeset 368 8a61842d00ce
parent 367 b2aa197f6774
child 451 48116d511e5d
     1.1 --- a/IMG_pcx.c	Thu Apr 25 00:22:51 2013 -0700
     1.2 +++ b/IMG_pcx.c	Tue May 21 21:24:32 2013 -0700
     1.3 @@ -42,221 +42,221 @@
     1.4  #ifdef LOAD_PCX
     1.5  
     1.6  struct PCXheader {
     1.7 -	Uint8 Manufacturer;
     1.8 -	Uint8 Version;
     1.9 -	Uint8 Encoding;
    1.10 -	Uint8 BitsPerPixel;
    1.11 -	Sint16 Xmin, Ymin, Xmax, Ymax;
    1.12 -	Sint16 HDpi, VDpi;
    1.13 -	Uint8 Colormap[48];
    1.14 -	Uint8 Reserved;
    1.15 -	Uint8 NPlanes;
    1.16 -	Sint16 BytesPerLine;
    1.17 -	Sint16 PaletteInfo;
    1.18 -	Sint16 HscreenSize;
    1.19 -	Sint16 VscreenSize;
    1.20 -	Uint8 Filler[54];
    1.21 +    Uint8 Manufacturer;
    1.22 +    Uint8 Version;
    1.23 +    Uint8 Encoding;
    1.24 +    Uint8 BitsPerPixel;
    1.25 +    Sint16 Xmin, Ymin, Xmax, Ymax;
    1.26 +    Sint16 HDpi, VDpi;
    1.27 +    Uint8 Colormap[48];
    1.28 +    Uint8 Reserved;
    1.29 +    Uint8 NPlanes;
    1.30 +    Sint16 BytesPerLine;
    1.31 +    Sint16 PaletteInfo;
    1.32 +    Sint16 HscreenSize;
    1.33 +    Sint16 VscreenSize;
    1.34 +    Uint8 Filler[54];
    1.35  };
    1.36  
    1.37  /* See if an image is contained in a data source */
    1.38  int IMG_isPCX(SDL_RWops *src)
    1.39  {
    1.40 -	Sint64 start;
    1.41 -	int is_PCX;
    1.42 -	const int ZSoft_Manufacturer = 10;
    1.43 -	const int PC_Paintbrush_Version = 5;
    1.44 -	const int PCX_Uncompressed_Encoding = 0;
    1.45 -	const int PCX_RunLength_Encoding = 1;
    1.46 -	struct PCXheader pcxh;
    1.47 +    Sint64 start;
    1.48 +    int is_PCX;
    1.49 +    const int ZSoft_Manufacturer = 10;
    1.50 +    const int PC_Paintbrush_Version = 5;
    1.51 +    const int PCX_Uncompressed_Encoding = 0;
    1.52 +    const int PCX_RunLength_Encoding = 1;
    1.53 +    struct PCXheader pcxh;
    1.54  
    1.55 -	if ( !src )
    1.56 -		return 0;
    1.57 -	start = SDL_RWtell(src);
    1.58 -	is_PCX = 0;
    1.59 -	if ( SDL_RWread(src, &pcxh, sizeof(pcxh), 1) == 1 ) {
    1.60 -		if ( (pcxh.Manufacturer == ZSoft_Manufacturer) &&
    1.61 -		     (pcxh.Version == PC_Paintbrush_Version) &&
    1.62 -		     (pcxh.Encoding == PCX_RunLength_Encoding ||
    1.63 -		      pcxh.Encoding == PCX_Uncompressed_Encoding) ) {
    1.64 -			is_PCX = 1;
    1.65 -		}
    1.66 -	}
    1.67 -	SDL_RWseek(src, start, RW_SEEK_SET);
    1.68 -	return(is_PCX);
    1.69 +    if ( !src )
    1.70 +        return 0;
    1.71 +    start = SDL_RWtell(src);
    1.72 +    is_PCX = 0;
    1.73 +    if ( SDL_RWread(src, &pcxh, sizeof(pcxh), 1) == 1 ) {
    1.74 +        if ( (pcxh.Manufacturer == ZSoft_Manufacturer) &&
    1.75 +             (pcxh.Version == PC_Paintbrush_Version) &&
    1.76 +             (pcxh.Encoding == PCX_RunLength_Encoding ||
    1.77 +              pcxh.Encoding == PCX_Uncompressed_Encoding) ) {
    1.78 +            is_PCX = 1;
    1.79 +        }
    1.80 +    }
    1.81 +    SDL_RWseek(src, start, RW_SEEK_SET);
    1.82 +    return(is_PCX);
    1.83  }
    1.84  
    1.85  /* Load a PCX type image from an SDL datasource */
    1.86  SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
    1.87  {
    1.88 -	Sint64 start;
    1.89 -	struct PCXheader pcxh;
    1.90 -	Uint32 Rmask;
    1.91 -	Uint32 Gmask;
    1.92 -	Uint32 Bmask;
    1.93 -	Uint32 Amask;
    1.94 -	SDL_Surface *surface = NULL;
    1.95 -	int width, height;
    1.96 -	int y, bpl;
    1.97 -	Uint8 *row, *buf = NULL;
    1.98 -	char *error = NULL;
    1.99 -	int bits, src_bits;
   1.100 +    Sint64 start;
   1.101 +    struct PCXheader pcxh;
   1.102 +    Uint32 Rmask;
   1.103 +    Uint32 Gmask;
   1.104 +    Uint32 Bmask;
   1.105 +    Uint32 Amask;
   1.106 +    SDL_Surface *surface = NULL;
   1.107 +    int width, height;
   1.108 +    int y, bpl;
   1.109 +    Uint8 *row, *buf = NULL;
   1.110 +    char *error = NULL;
   1.111 +    int bits, src_bits;
   1.112  
   1.113 -	if ( !src ) {
   1.114 -		/* The error message has been set in SDL_RWFromFile */
   1.115 -		return NULL;
   1.116 -	}
   1.117 -	start = SDL_RWtell(src);
   1.118 +    if ( !src ) {
   1.119 +        /* The error message has been set in SDL_RWFromFile */
   1.120 +        return NULL;
   1.121 +    }
   1.122 +    start = SDL_RWtell(src);
   1.123  
   1.124 -	if ( ! SDL_RWread(src, &pcxh, sizeof(pcxh), 1) ) {
   1.125 -		error = "file truncated";
   1.126 -		goto done;
   1.127 -	}
   1.128 -	pcxh.Xmin = SDL_SwapLE16(pcxh.Xmin);
   1.129 -	pcxh.Ymin = SDL_SwapLE16(pcxh.Ymin);
   1.130 -	pcxh.Xmax = SDL_SwapLE16(pcxh.Xmax);
   1.131 -	pcxh.Ymax = SDL_SwapLE16(pcxh.Ymax);
   1.132 -	pcxh.BytesPerLine = SDL_SwapLE16(pcxh.BytesPerLine);
   1.133 +    if ( ! SDL_RWread(src, &pcxh, sizeof(pcxh), 1) ) {
   1.134 +        error = "file truncated";
   1.135 +        goto done;
   1.136 +    }
   1.137 +    pcxh.Xmin = SDL_SwapLE16(pcxh.Xmin);
   1.138 +    pcxh.Ymin = SDL_SwapLE16(pcxh.Ymin);
   1.139 +    pcxh.Xmax = SDL_SwapLE16(pcxh.Xmax);
   1.140 +    pcxh.Ymax = SDL_SwapLE16(pcxh.Ymax);
   1.141 +    pcxh.BytesPerLine = SDL_SwapLE16(pcxh.BytesPerLine);
   1.142  
   1.143 -	/* Create the surface of the appropriate type */
   1.144 -	width = (pcxh.Xmax - pcxh.Xmin) + 1;
   1.145 -	height = (pcxh.Ymax - pcxh.Ymin) + 1;
   1.146 -	Rmask = Gmask = Bmask = Amask = 0;
   1.147 -	src_bits = pcxh.BitsPerPixel * pcxh.NPlanes;
   1.148 -	if((pcxh.BitsPerPixel == 1 && pcxh.NPlanes >= 1 && pcxh.NPlanes <= 4)
   1.149 -	   || (pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 1)) {
   1.150 -		bits = 8;
   1.151 -	} else if(pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 3) {
   1.152 -		bits = 24;
   1.153 +    /* Create the surface of the appropriate type */
   1.154 +    width = (pcxh.Xmax - pcxh.Xmin) + 1;
   1.155 +    height = (pcxh.Ymax - pcxh.Ymin) + 1;
   1.156 +    Rmask = Gmask = Bmask = Amask = 0;
   1.157 +    src_bits = pcxh.BitsPerPixel * pcxh.NPlanes;
   1.158 +    if((pcxh.BitsPerPixel == 1 && pcxh.NPlanes >= 1 && pcxh.NPlanes <= 4)
   1.159 +       || (pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 1)) {
   1.160 +        bits = 8;
   1.161 +    } else if(pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 3) {
   1.162 +        bits = 24;
   1.163  #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.164 -			Rmask = 0x000000FF;
   1.165 -			Gmask = 0x0000FF00;
   1.166 -			Bmask = 0x00FF0000;
   1.167 +            Rmask = 0x000000FF;
   1.168 +            Gmask = 0x0000FF00;
   1.169 +            Bmask = 0x00FF0000;
   1.170  #else
   1.171 -			Rmask = 0xFF0000;
   1.172 -			Gmask = 0x00FF00;
   1.173 -			Bmask = 0x0000FF;
   1.174 +            Rmask = 0xFF0000;
   1.175 +            Gmask = 0x00FF00;
   1.176 +            Bmask = 0x0000FF;
   1.177  #endif
   1.178 -	} else {
   1.179 -		error = "unsupported PCX format";
   1.180 -		goto done;
   1.181 -	}
   1.182 -	surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
   1.183 -				   bits, Rmask, Gmask, Bmask, Amask);
   1.184 -	if ( surface == NULL )
   1.185 -		goto done;
   1.186 +    } else {
   1.187 +        error = "unsupported PCX format";
   1.188 +        goto done;
   1.189 +    }
   1.190 +    surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
   1.191 +                   bits, Rmask, Gmask, Bmask, Amask);
   1.192 +    if ( surface == NULL )
   1.193 +        goto done;
   1.194  
   1.195 -	bpl = pcxh.NPlanes * pcxh.BytesPerLine;
   1.196 -	if (bpl > surface->pitch) {
   1.197 -		error = "bytes per line is too large (corrupt?)";
   1.198 -	}
   1.199 -	buf = (Uint8 *)SDL_malloc(bpl);
   1.200 -	row = (Uint8 *)surface->pixels;
   1.201 -	for ( y=0; y<surface->h; ++y ) {
   1.202 -		/* decode a scan line to a temporary buffer first */
   1.203 -		int i, count = 0;
   1.204 -		Uint8 ch;
   1.205 -		Uint8 *dst = (src_bits == 8) ? row : buf;
   1.206 -		if ( pcxh.Encoding == 0 ) {
   1.207 -			if(!SDL_RWread(src, dst, bpl, 1)) {
   1.208 -				error = "file truncated";
   1.209 -				goto done;
   1.210 -			}
   1.211 -		} else {
   1.212 -			for(i = 0; i < bpl; i++) {
   1.213 -				if(!count) {
   1.214 -					if(!SDL_RWread(src, &ch, 1, 1)) {
   1.215 -						error = "file truncated";
   1.216 -						goto done;
   1.217 -					}
   1.218 -					if( (ch & 0xc0) == 0xc0) {
   1.219 -						count = ch & 0x3f;
   1.220 -						if(!SDL_RWread(src, &ch, 1, 1)) {
   1.221 -							error = "file truncated";
   1.222 -							goto done;
   1.223 -						}
   1.224 -					} else
   1.225 -						count = 1;
   1.226 -				}
   1.227 -				dst[i] = ch;
   1.228 -				count--;
   1.229 -			}
   1.230 -		}
   1.231 +    bpl = pcxh.NPlanes * pcxh.BytesPerLine;
   1.232 +    if (bpl > surface->pitch) {
   1.233 +        error = "bytes per line is too large (corrupt?)";
   1.234 +    }
   1.235 +    buf = (Uint8 *)SDL_malloc(bpl);
   1.236 +    row = (Uint8 *)surface->pixels;
   1.237 +    for ( y=0; y<surface->h; ++y ) {
   1.238 +        /* decode a scan line to a temporary buffer first */
   1.239 +        int i, count = 0;
   1.240 +        Uint8 ch;
   1.241 +        Uint8 *dst = (src_bits == 8) ? row : buf;
   1.242 +        if ( pcxh.Encoding == 0 ) {
   1.243 +            if(!SDL_RWread(src, dst, bpl, 1)) {
   1.244 +                error = "file truncated";
   1.245 +                goto done;
   1.246 +            }
   1.247 +        } else {
   1.248 +            for(i = 0; i < bpl; i++) {
   1.249 +                if(!count) {
   1.250 +                    if(!SDL_RWread(src, &ch, 1, 1)) {
   1.251 +                        error = "file truncated";
   1.252 +                        goto done;
   1.253 +                    }
   1.254 +                    if( (ch & 0xc0) == 0xc0) {
   1.255 +                        count = ch & 0x3f;
   1.256 +                        if(!SDL_RWread(src, &ch, 1, 1)) {
   1.257 +                            error = "file truncated";
   1.258 +                            goto done;
   1.259 +                        }
   1.260 +                    } else
   1.261 +                        count = 1;
   1.262 +                }
   1.263 +                dst[i] = ch;
   1.264 +                count--;
   1.265 +            }
   1.266 +        }
   1.267  
   1.268 -		if(src_bits <= 4) {
   1.269 -			/* expand planes to 1 byte/pixel */
   1.270 -			Uint8 *innerSrc = buf;
   1.271 -			int plane;
   1.272 -			for(plane = 0; plane < pcxh.NPlanes; plane++) {
   1.273 -				int j, k, x = 0;
   1.274 -				for(j = 0; j < pcxh.BytesPerLine; j++) {
   1.275 -					Uint8 byte = *innerSrc++;
   1.276 -					for(k = 7; k >= 0; k--) {
   1.277 -						unsigned bit = (byte >> k) & 1;
   1.278 -						/* skip padding bits */
   1.279 -						if (j * 8 + k >= width)
   1.280 -							continue;
   1.281 -						row[x++] |= bit << plane;
   1.282 -					}
   1.283 -				}
   1.284 -			}
   1.285 - 		} else if(src_bits == 24) {
   1.286 -			/* de-interlace planes */
   1.287 -			Uint8 *innerSrc = buf;
   1.288 -			int plane;
   1.289 -			for(plane = 0; plane < pcxh.NPlanes; plane++) {
   1.290 -				int x;
   1.291 -				dst = row + plane;
   1.292 -				for(x = 0; x < width; x++) {
   1.293 -					*dst = *innerSrc++;
   1.294 -					dst += pcxh.NPlanes;
   1.295 -				}
   1.296 -			}
   1.297 -		}
   1.298 +        if(src_bits <= 4) {
   1.299 +            /* expand planes to 1 byte/pixel */
   1.300 +            Uint8 *innerSrc = buf;
   1.301 +            int plane;
   1.302 +            for(plane = 0; plane < pcxh.NPlanes; plane++) {
   1.303 +                int j, k, x = 0;
   1.304 +                for(j = 0; j < pcxh.BytesPerLine; j++) {
   1.305 +                    Uint8 byte = *innerSrc++;
   1.306 +                    for(k = 7; k >= 0; k--) {
   1.307 +                        unsigned bit = (byte >> k) & 1;
   1.308 +                        /* skip padding bits */
   1.309 +                        if (j * 8 + k >= width)
   1.310 +                            continue;
   1.311 +                        row[x++] |= bit << plane;
   1.312 +                    }
   1.313 +                }
   1.314 +            }
   1.315 +        } else if(src_bits == 24) {
   1.316 +            /* de-interlace planes */
   1.317 +            Uint8 *innerSrc = buf;
   1.318 +            int plane;
   1.319 +            for(plane = 0; plane < pcxh.NPlanes; plane++) {
   1.320 +                int x;
   1.321 +                dst = row + plane;
   1.322 +                for(x = 0; x < width; x++) {
   1.323 +                    *dst = *innerSrc++;
   1.324 +                    dst += pcxh.NPlanes;
   1.325 +                }
   1.326 +            }
   1.327 +        }
   1.328  
   1.329 -		row += surface->pitch;
   1.330 -	}
   1.331 +        row += surface->pitch;
   1.332 +    }
   1.333  
   1.334 -	if(bits == 8) {
   1.335 -		SDL_Color *colors = surface->format->palette->colors;
   1.336 -		int nc = 1 << src_bits;
   1.337 -		int i;
   1.338 +    if(bits == 8) {
   1.339 +        SDL_Color *colors = surface->format->palette->colors;
   1.340 +        int nc = 1 << src_bits;
   1.341 +        int i;
   1.342  
   1.343 -		surface->format->palette->ncolors = nc;
   1.344 -		if(src_bits == 8) {
   1.345 -			Uint8 ch;
   1.346 -			/* look for a 256-colour palette */
   1.347 -			do {
   1.348 -				if ( !SDL_RWread(src, &ch, 1, 1)) {
   1.349 -					error = "file truncated";
   1.350 -					goto done;
   1.351 -				}
   1.352 -			} while ( ch != 12 );
   1.353 +        surface->format->palette->ncolors = nc;
   1.354 +        if(src_bits == 8) {
   1.355 +            Uint8 ch;
   1.356 +            /* look for a 256-colour palette */
   1.357 +            do {
   1.358 +                if ( !SDL_RWread(src, &ch, 1, 1)) {
   1.359 +                    error = "file truncated";
   1.360 +                    goto done;
   1.361 +                }
   1.362 +            } while ( ch != 12 );
   1.363  
   1.364 -			for(i = 0; i < 256; i++) {
   1.365 -				SDL_RWread(src, &colors[i].r, 1, 1);
   1.366 -				SDL_RWread(src, &colors[i].g, 1, 1);
   1.367 -				SDL_RWread(src, &colors[i].b, 1, 1);
   1.368 -			}
   1.369 -		} else {
   1.370 -			for(i = 0; i < nc; i++) {
   1.371 -				colors[i].r = pcxh.Colormap[i * 3];
   1.372 -				colors[i].g = pcxh.Colormap[i * 3 + 1];
   1.373 -				colors[i].b = pcxh.Colormap[i * 3 + 2];
   1.374 -			}
   1.375 -		}
   1.376 -	}
   1.377 +            for(i = 0; i < 256; i++) {
   1.378 +                SDL_RWread(src, &colors[i].r, 1, 1);
   1.379 +                SDL_RWread(src, &colors[i].g, 1, 1);
   1.380 +                SDL_RWread(src, &colors[i].b, 1, 1);
   1.381 +            }
   1.382 +        } else {
   1.383 +            for(i = 0; i < nc; i++) {
   1.384 +                colors[i].r = pcxh.Colormap[i * 3];
   1.385 +                colors[i].g = pcxh.Colormap[i * 3 + 1];
   1.386 +                colors[i].b = pcxh.Colormap[i * 3 + 2];
   1.387 +            }
   1.388 +        }
   1.389 +    }
   1.390  
   1.391  done:
   1.392 -	SDL_free(buf);
   1.393 -	if ( error ) {
   1.394 -		SDL_RWseek(src, start, RW_SEEK_SET);
   1.395 -		if ( surface ) {
   1.396 -			SDL_FreeSurface(surface);
   1.397 -			surface = NULL;
   1.398 -		}
   1.399 -		IMG_SetError(error);
   1.400 -	}
   1.401 -	return(surface);
   1.402 +    SDL_free(buf);
   1.403 +    if ( error ) {
   1.404 +        SDL_RWseek(src, start, RW_SEEK_SET);
   1.405 +        if ( surface ) {
   1.406 +            SDL_FreeSurface(surface);
   1.407 +            surface = NULL;
   1.408 +        }
   1.409 +        IMG_SetError(error);
   1.410 +    }
   1.411 +    return(surface);
   1.412  }
   1.413  
   1.414  #else
   1.415 @@ -264,13 +264,13 @@
   1.416  /* See if an image is contained in a data source */
   1.417  int IMG_isPCX(SDL_RWops *src)
   1.418  {
   1.419 -	return(0);
   1.420 +    return(0);
   1.421  }
   1.422  
   1.423  /* Load a PCX type image from an SDL datasource */
   1.424  SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
   1.425  {
   1.426 -	return(NULL);
   1.427 +    return(NULL);
   1.428  }
   1.429  
   1.430  #endif /* LOAD_PCX */