| | |
| | | /* |
| | | * Calculate the pad-aligned scanline width of a surface |
| | | */ |
| | | static int |
| | | static Sint64 |
| | | SDL_CalculatePitch(Uint32 format, int width) |
| | | { |
| | | int pitch; |
| | | Sint64 pitch; |
| | | |
| | | if (SDL_ISPIXELFORMAT_FOURCC(format) || SDL_BITSPERPIXEL(format) >= 8) { |
| | | pitch = (width * SDL_BYTESPERPIXEL(format)); |
| | | pitch = ((Sint64)width * SDL_BYTESPERPIXEL(format)); |
| | | } else { |
| | | pitch = ((width * SDL_BITSPERPIXEL(format)) + 7) / 8; |
| | | pitch = (((Sint64)width * SDL_BITSPERPIXEL(format)) + 7) / 8; |
| | | } |
| | | pitch = (pitch + 3) & ~3; /* 4-byte aligning for speed */ |
| | | return pitch; |
| | |
| | | SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, |
| | | Uint32 format) |
| | | { |
| | | Sint64 pitch; |
| | | SDL_Surface *surface; |
| | | |
| | | /* The flags are no longer used, make the compiler happy */ |
| | | (void)flags; |
| | | |
| | | pitch = SDL_CalculatePitch(format, width); |
| | | if (pitch < 0 || pitch > SDL_MAX_SINT32) { |
| | | /* Overflow... */ |
| | | SDL_OutOfMemory(); |
| | | return NULL; |
| | | } |
| | | |
| | | /* Allocate the surface */ |
| | | surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface)); |
| | |
| | | } |
| | | surface->w = width; |
| | | surface->h = height; |
| | | surface->pitch = SDL_CalculatePitch(format, width); |
| | | surface->pitch = (int)pitch; |
| | | SDL_SetClipRect(surface, NULL); |
| | | |
| | | if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) { |
| | |
| | | SDL_InvalidateMap(surface->map); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | SDL_bool |
| | | SDL_HasSurfaceRLE(SDL_Surface * surface) |
| | | { |
| | | if (!surface) { |
| | | return SDL_FALSE; |
| | | } |
| | | |
| | | if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) { |
| | | return SDL_FALSE; |
| | | } |
| | | |
| | | return SDL_TRUE; |
| | | } |
| | | |
| | | int |
| | |
| | | surface->map->info.g = 0xFF; |
| | | surface->map->info.b = 0xFF; |
| | | surface->map->info.a = 0xFF; |
| | | surface->map->info.flags = 0; |
| | | surface->map->info.flags = (copy_flags & (SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY)); |
| | | SDL_InvalidateMap(surface->map); |
| | | |
| | | /* Copy over the image data */ |
| | |
| | | * -> set alpha channel to be opaque */ |
| | | if (surface->format->palette && format->Amask) { |
| | | SDL_bool set_opaque = SDL_FALSE; |
| | | { |
| | | int i; |
| | | for (i = 0; i < surface->format->palette->ncolors; i++) { |
| | | Uint8 alpha_value = surface->format->palette->colors[i].a; |
| | | |
| | | if (alpha_value != 0 && alpha_value != SDL_ALPHA_OPAQUE) { |
| | | /* Palette has at least one alpha value. Don't do anything */ |
| | | set_opaque = SDL_FALSE; |
| | | palette_has_alpha = SDL_TRUE; |
| | | break; |
| | | } |
| | | SDL_bool is_opaque, has_alpha_channel; |
| | | SDL_DetectPalette(surface->format->palette, &is_opaque, &has_alpha_channel); |
| | | |
| | | if (alpha_value == 0) { |
| | | set_opaque = SDL_TRUE; |
| | | } |
| | | if (is_opaque) { |
| | | if (!has_alpha_channel) { |
| | | set_opaque = SDL_TRUE; |
| | | } |
| | | } else { |
| | | palette_has_alpha = SDL_TRUE; |
| | | } |
| | | |
| | | /* Set opaque and backup palette alpha values */ |
| | |
| | | |
| | | if (copy_flags & SDL_COPY_COLORKEY) { |
| | | SDL_bool set_colorkey_by_color = SDL_FALSE; |
| | | SDL_bool convert_colorkey = SDL_TRUE; |
| | | |
| | | if (surface->format->palette) { |
| | | if (format->palette && |
| | |
| | | /* The palette is identical, just set the same colorkey */ |
| | | SDL_SetColorKey(convert, 1, surface->map->info.colorkey); |
| | | } else if (!format->palette) { |
| | | /* Was done by 'palette_ck_transform' */ |
| | | if (format->Amask) { |
| | | /* No need to add the colorkey, transparency is in the alpha channel*/ |
| | | } else { |
| | | /* Only set the colorkey information */ |
| | | set_colorkey_by_color = SDL_TRUE; |
| | | convert_colorkey = SDL_FALSE; |
| | | } |
| | | } else { |
| | | set_colorkey_by_color = SDL_TRUE; |
| | | } |
| | |
| | | SDL_SetColorKey(convert, 1, converted_colorkey); |
| | | |
| | | /* This is needed when converting for 3D texture upload */ |
| | | SDL_ConvertColorkeyToAlpha(convert, SDL_TRUE); |
| | | if (convert_colorkey) { |
| | | SDL_ConvertColorkeyToAlpha(convert, SDL_TRUE); |
| | | } |
| | | } |
| | | } |
| | | SDL_SetClipRect(convert, &surface->clip_rect); |
| | |
| | | SDL_BlitMap src_blitmap, dst_blitmap; |
| | | SDL_Rect rect; |
| | | void *nonconst_src = (void *) src; |
| | | int ret; |
| | | |
| | | /* Check to make sure we are blitting somewhere, so we don't crash */ |
| | | if (!dst) { |
| | |
| | | rect.y = 0; |
| | | rect.w = width; |
| | | rect.h = height; |
| | | return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect); |
| | | ret = SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect); |
| | | |
| | | /* Free blitmap reference, after blitting between stack'ed surfaces */ |
| | | SDL_InvalidateMap(src_surface.map); |
| | | |
| | | return ret; |
| | | } |
| | | |
| | | /* |
| | |
| | | } |
| | | SDL_InvalidateMap(surface->map); |
| | | |
| | | SDL_InvalidateAllBlitMap(surface); |
| | | |
| | | if (--surface->refcount > 0) { |
| | | return; |
| | | } |