IMG_tga.c
changeset 343 5bf0f0d6a74e
parent 322 92e073f230d0
child 347 ad5034cad524
equal deleted inserted replaced
341:18ab81286e51 343:5bf0f0d6a74e
    85 #define SETLE16(p, v) ((p)[0] = (v), (p)[1] = (v) >> 8)
    85 #define SETLE16(p, v) ((p)[0] = (v), (p)[1] = (v) >> 8)
    86 
    86 
    87 /* Load a TGA type image from an SDL datasource */
    87 /* Load a TGA type image from an SDL datasource */
    88 SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
    88 SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
    89 {
    89 {
    90     int start;
    90     Sint64 start;
    91     const char *error = NULL;
    91     const char *error = NULL;
    92     struct TGAheader hdr;
    92     struct TGAheader hdr;
    93     int rle = 0;
    93     int rle = 0;
    94     int alpha = 0;
    94     int alpha = 0;
    95     int indexed = 0;
    95     int indexed = 0;
   167 
   167 
   168     case 32:
   168     case 32:
   169 	alpha = 1;
   169 	alpha = 1;
   170 	/* fallthrough */
   170 	/* fallthrough */
   171     case 24:
   171     case 24:
   172 	if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
   172 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
       
   173 		{
   173 	    int s = alpha ? 0 : 8;
   174 	    int s = alpha ? 0 : 8;
   174 	    amask = 0x000000ff >> s;
   175 	    amask = 0x000000ff >> s;
   175 	    rmask = 0x0000ff00 >> s;
   176 	    rmask = 0x0000ff00 >> s;
   176 	    gmask = 0x00ff0000 >> s;
   177 	    gmask = 0x00ff0000 >> s;
   177 	    bmask = 0xff000000 >> s;
   178 	    bmask = 0xff000000 >> s;
   178 	} else {
   179 		}
       
   180 #else
   179 	    amask = alpha ? 0xff000000 : 0;
   181 	    amask = alpha ? 0xff000000 : 0;
   180 	    rmask = 0x00ff0000;
   182 	    rmask = 0x00ff0000;
   181 	    gmask = 0x0000ff00;
   183 	    gmask = 0x0000ff00;
   182 	    bmask = 0x000000ff;
   184 	    bmask = 0x000000ff;
   183 	}
   185 #endif
   184 	break;
   186 	break;
   185 
   187 
   186     default:
   188     default:
   187         goto unsupported;
   189         goto unsupported;
   188     }
   190     }
   205     }
   207     }
   206 
   208 
   207     if(hdr.has_cmap) {
   209     if(hdr.has_cmap) {
   208 	int palsiz = ncols * ((hdr.cmap_bits + 7) >> 3);
   210 	int palsiz = ncols * ((hdr.cmap_bits + 7) >> 3);
   209 	if(indexed && !grey) {
   211 	if(indexed && !grey) {
   210 	    Uint8 *pal = malloc(palsiz), *p = pal;
   212 	    Uint8 *pal = (Uint8 *)SDL_malloc(palsiz), *p = pal;
   211 	    SDL_Color *colors = img->format->palette->colors;
   213 	    SDL_Color *colors = img->format->palette->colors;
   212 	    img->format->palette->ncolors = ncols;
   214 	    img->format->palette->ncolors = ncols;
   213 	    SDL_RWread(src, pal, palsiz, 1);
   215 	    SDL_RWread(src, pal, palsiz, 1);
   214 	    for(i = 0; i < ncols; i++) {
   216 	    for(i = 0; i < ncols; i++) {
   215 		switch(hdr.cmap_bits) {
   217 		switch(hdr.cmap_bits) {
   231 		    if(hdr.cmap_bits == 32 && *p++ < 128)
   233 		    if(hdr.cmap_bits == 32 && *p++ < 128)
   232 			ckey = i;
   234 			ckey = i;
   233 		    break;
   235 		    break;
   234 		}
   236 		}
   235 	    }
   237 	    }
   236 	    free(pal);
   238 	    SDL_free(pal);
   237 	    if(ckey >= 0)
   239 	    if(ckey >= 0)
   238 		SDL_SetColorKey(img, SDL_TRUE, ckey);
   240 		SDL_SetColorKey(img, SDL_TRUE, ckey);
   239 	} else {
   241 	} else {
   240 	    /* skip unneeded colormap */
   242 	    /* skip unneeded colormap */
   241 	    SDL_RWseek(src, palsiz, RW_SEEK_CUR);
   243 	    SDL_RWseek(src, palsiz, RW_SEEK_CUR);
   248 	    colors[i].r = colors[i].g = colors[i].b = i;
   250 	    colors[i].r = colors[i].g = colors[i].b = i;
   249 	img->format->palette->ncolors = 256;
   251 	img->format->palette->ncolors = 256;
   250     }
   252     }
   251 
   253 
   252     if(hdr.flags & TGA_ORIGIN_UPPER) {
   254     if(hdr.flags & TGA_ORIGIN_UPPER) {
   253 	lstep = img->pitch;
   255 		lstep = img->pitch;
   254 	dst = img->pixels;
   256 		dst = (Uint8 *)img->pixels;
   255     } else {
   257     } else {
   256 	lstep = -img->pitch;
   258 		lstep = -img->pitch;
   257 	dst = (Uint8 *)img->pixels + (h - 1) * img->pitch;
   259 		dst = (Uint8 *)img->pixels + (h - 1) * img->pitch;
   258     }
   260     }
   259 
   261 
   260     /* The RLE decoding code is slightly convoluted since we can't rely on
   262     /* The RLE decoding code is slightly convoluted since we can't rely on
   261        spans not to wrap across scan lines */
   263        spans not to wrap across scan lines */
   262     count = rep = 0;
   264     count = rep = 0;
   279 		    int n = rep;
   281 		    int n = rep;
   280 		    if(n > w - x)
   282 		    if(n > w - x)
   281 			n = w - x;
   283 			n = w - x;
   282 		    rep -= n;
   284 		    rep -= n;
   283 		    while(n--) {
   285 		    while(n--) {
   284 			memcpy(dst + x * bpp, &pixel, bpp);
   286 			SDL_memcpy(dst + x * bpp, &pixel, bpp);
   285 			x++;
   287 			x++;
   286 		    }
   288 		    }
   287 		    if(x == w)
   289 		    if(x == w)
   288 			break;
   290 			break;
   289 		}
   291 		}
   298 	    }
   300 	    }
   299 
   301 
   300 	} else {
   302 	} else {
   301 	    SDL_RWread(src, dst, w * bpp, 1);
   303 	    SDL_RWread(src, dst, w * bpp, 1);
   302 	}
   304 	}
   303 	if(SDL_BYTEORDER == SDL_BIG_ENDIAN && bpp == 2) {
   305 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
       
   306 	if (bpp == 2) {
   304 	    /* swap byte order */
   307 	    /* swap byte order */
   305 	    int x;
   308 	    int x;
   306 	    Uint16 *p = (Uint16 *)dst;
   309 	    Uint16 *p = (Uint16 *)dst;
   307 	    for(x = 0; x < w; x++)
   310 	    for(x = 0; x < w; x++)
   308 		p[x] = SDL_Swap16(p[x]);
   311 		p[x] = SDL_Swap16(p[x]);
   309 	}
   312 	}
       
   313 #endif
   310 	dst += lstep;
   314 	dst += lstep;
   311     }
   315     }
   312     return img;
   316     return img;
   313 
   317 
   314 unsupported:
   318 unsupported: