示例#1
0
/* Perform a stretch blit between two surfaces of the same format.
 NOTE:  This function is not safe to call from multiple threads!
 */
int egl_soft_stretch(uint8_t* src, int s_x, int s_y, int s_w, int s_h,
		uint8_t* dst, int d_x, int d_y, int d_w, int d_h, int bpp) {
	int src_locked;
	int dst_locked;
	int pos, inc;
	int dst_maxrow;
	int src_row, dst_row;
	uint8_t *srcp = NULL;
	uint8_t *dstp;

	/* Set up the data... */
	pos = 0x10000;
	inc = (s_h << 16) / d_h;
	src_row = s_y;
	dst_row = d_y;

	/* Perform the stretch blit */
	for (dst_maxrow = dst_row + d_h; dst_row < dst_maxrow; ++dst_row) {
		dstp = (uint8_t *) dst + (dst_row * d_w) + (d_x * bpp);
		while (pos >= 0x10000L) {
			srcp = (uint8_t *) src + (src_row * s_w) + (s_x * bpp);
			++src_row;
			pos -= 0x10000L;
		}
		switch (bpp) {
		case 1:
			copy_row1(srcp, s_w, dstp, d_w);
			break;
		case 2:
			copy_row2((uint16_t *) srcp, s_w, (uint16_t *) dstp, d_w);
			break;
		case 3:
			copy_row3(srcp, s_w, dstp, d_w);
			break;
		case 4:
			copy_row4((uint32_t *) srcp, s_w, (uint32_t *) dstp, d_w);
			break;
		}
		pos += inc;
	}

	return 1;
}
示例#2
0
/* Perform a stretch blit between two surfaces of the same format.
   NOTE:  This function is not safe to call from multiple threads!
*/
int
SDL_SoftStretch(SDL_Surface * src, const SDL_Rect * srcrect,
                SDL_Surface * dst, const SDL_Rect * dstrect)
{
    int src_locked;
    int dst_locked;
    int pos, inc;
    int dst_maxrow;
    int src_row, dst_row;
    Uint8 *srcp = NULL;
    Uint8 *dstp;
    SDL_Rect full_src;
    SDL_Rect full_dst;
#ifdef USE_ASM_STRETCH
    SDL_bool use_asm = SDL_TRUE;
#ifdef __GNUC__
    int u1, u2;
#endif
#endif /* USE_ASM_STRETCH */
    const int bpp = dst->format->BytesPerPixel;

    if (src->format->format != dst->format->format) {
        return SDL_SetError("Only works with same format surfaces");
    }

    /* Verify the blit rectangles */
    if (srcrect) {
        if ((srcrect->x < 0) || (srcrect->y < 0) ||
            ((srcrect->x + srcrect->w) > src->w) ||
            ((srcrect->y + srcrect->h) > src->h)) {
            return SDL_SetError("Invalid source blit rectangle");
        }
    } else {
        full_src.x = 0;
        full_src.y = 0;
        full_src.w = src->w;
        full_src.h = src->h;
        srcrect = &full_src;
    }
    if (dstrect) {
        if ((dstrect->x < 0) || (dstrect->y < 0) ||
            ((dstrect->x + dstrect->w) > dst->w) ||
            ((dstrect->y + dstrect->h) > dst->h)) {
            return SDL_SetError("Invalid destination blit rectangle");
        }
    } else {
        full_dst.x = 0;
        full_dst.y = 0;
        full_dst.w = dst->w;
        full_dst.h = dst->h;
        dstrect = &full_dst;
    }

    /* Lock the destination if it's in hardware */
    dst_locked = 0;
    if (SDL_MUSTLOCK(dst)) {
        if (SDL_LockSurface(dst) < 0) {
            return SDL_SetError("Unable to lock destination surface");
        }
        dst_locked = 1;
    }
    /* Lock the source if it's in hardware */
    src_locked = 0;
    if (SDL_MUSTLOCK(src)) {
        if (SDL_LockSurface(src) < 0) {
            if (dst_locked) {
                SDL_UnlockSurface(dst);
            }
            return SDL_SetError("Unable to lock source surface");
        }
        src_locked = 1;
    }

    /* Set up the data... */
    pos = 0x10000;
    inc = (srcrect->h << 16) / dstrect->h;
    src_row = srcrect->y;
    dst_row = dstrect->y;

#ifdef USE_ASM_STRETCH
    /* Write the opcodes for this stretch */
    if ((bpp == 3) || (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0)) {
        use_asm = SDL_FALSE;
    }
#endif

    /* Perform the stretch blit */
    for (dst_maxrow = dst_row + dstrect->h; dst_row < dst_maxrow; ++dst_row) {
        dstp = (Uint8 *) dst->pixels + (dst_row * dst->pitch)
            + (dstrect->x * bpp);
        while (pos >= 0x10000L) {
            srcp = (Uint8 *) src->pixels + (src_row * src->pitch)
                + (srcrect->x * bpp);
            ++src_row;
            pos -= 0x10000L;
        }
#ifdef USE_ASM_STRETCH
        if (use_asm) {
#ifdef __GNUC__
            __asm__ __volatile__("call *%4":"=&D"(u1), "=&S"(u2)
                                 :"0"(dstp), "1"(srcp), "r"(copy_row)
                                 :"memory");
#elif defined(_MSC_VER) || defined(__WATCOMC__)
            /* *INDENT-OFF* */
            {
                void *code = copy_row;
                __asm {
                    push edi
                    push esi
                    mov edi, dstp
                    mov esi, srcp
                    call dword ptr code
                    pop esi
                    pop edi
                }
            }
            /* *INDENT-ON* */
#else
#error Need inline assembly for this compiler
#endif
        } else
#endif
            switch (bpp) {
            case 1:
                copy_row1(srcp, srcrect->w, dstp, dstrect->w);
                break;
            case 2:
                copy_row2((Uint16 *) srcp, srcrect->w,
                          (Uint16 *) dstp, dstrect->w);
                break;
            case 3:
                copy_row3(srcp, srcrect->w, dstp, dstrect->w);
                break;
            case 4:
                copy_row4((Uint32 *) srcp, srcrect->w,
                          (Uint32 *) dstp, dstrect->w);
                break;
            }
        pos += inc;
    }
示例#3
0
/**
 * Perform a stretch blit between two image structs of the same format.
 *
 * @param src Source image.
 * @param srcrect Source rectangle.
 * @param dst Destination image.
 * @param dstrect Destination rectangle.
 */
void
GdStretchImage(PMWIMAGEHDR src, MWCLIPRECT *srcrect, PMWIMAGEHDR dst,
	MWCLIPRECT *dstrect)
{
	int pos, inc;
	int bytesperpixel;
	int dst_maxrow;
	int src_row, dst_row;
	MWUCHAR *srcp = 0;
	MWUCHAR *dstp;
	MWCLIPRECT full_src;
	MWCLIPRECT full_dst;

	if ( src->bytesperpixel != dst->bytesperpixel ) {
		EPRINTF("GdStretchImage: bytesperpixel mismatch\n");
		return;
	}

	/* Verify the blit rectangles */
	if ( srcrect ) {
		if ( (srcrect->x < 0) || (srcrect->y < 0) ||
		     ((srcrect->x+srcrect->width) > src->width) ||
		     ((srcrect->y+srcrect->height) > src->height) ) {
			EPRINTF("GdStretchImage: invalid source rect\n");
			return;
		}
	} else {
		full_src.x = 0;
		full_src.y = 0;
		full_src.width = src->width;
		full_src.height = src->height;
		srcrect = &full_src;
	}
	if ( dstrect ) {
		/* if stretching to nothing, return*/
		if (!dstrect->width || !dstrect->height)
			return;
		if ( (dstrect->x < 0) || (dstrect->y < 0) ||
		     ((dstrect->x+dstrect->width) > dst->width) ||
		     ((dstrect->y+dstrect->height) > dst->height) ) {
			EPRINTF("GdStretchImage: invalid dest rect\n");
			return;
		}
	} else {
		full_dst.x = 0;
		full_dst.y = 0;
		full_dst.width = dst->width;
		full_dst.height = dst->height;
		dstrect = &full_dst;
	}

	/* Set up the data... */
	pos = 0x10000;
	inc = (srcrect->height << 16) / dstrect->height;
	src_row = srcrect->y;
	dst_row = dstrect->y;
	bytesperpixel = dst->bytesperpixel;

	/* Perform the stretch blit */
	for ( dst_maxrow = dst_row+dstrect->height; dst_row<dst_maxrow;
								++dst_row ) {
		dstp = (MWUCHAR *)dst->imagebits + (dst_row*dst->pitch)
				    + (dstrect->x*bytesperpixel);
		while ( pos >= 0x10000L ) {
			srcp = (MWUCHAR *)src->imagebits + (src_row*src->pitch)
				    + (srcrect->x*bytesperpixel);
			++src_row;
			pos -= 0x10000L;
		}

		switch (bytesperpixel) {
		case 1:
			copy_row1(srcp, srcrect->width, dstp, dstrect->width);
			break;
		case 2:
			copy_row2((unsigned short *)srcp, srcrect->width,
				(unsigned short *)dstp, dstrect->width);
			break;
		case 3:
			copy_row3(srcp, srcrect->width, dstp, dstrect->width);
			break;
		case 4:
			copy_row4((uint32_t *)srcp, srcrect->width,
				(uint32_t *)dstp, dstrect->width);
			break;
		}

		pos += inc;
	}
}