- return dst;
- }
- }
-#endif
-
- // FIXME: Horizontal and vertical line problem
-#ifdef BRESENHAM
- void accumulate(SDL_Surface *src, int srcx, int srcy, int color[4], int weight)
- {
- if(srcx < 0 || srcy < 0 || weight == 0) {
- return;
- }
- int bpp = src->format->BytesPerPixel;
- Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
- color[0] += red * weight;
- color[1] += green * weight;
- color[2] += blue * weight;
- color[3] += alpha * weight;
- }
-
- void accumulate_line(SDL_Surface *src, int srcy, int line[][4], int linesize, int weight, int numerator, int denominator)
- {
- int intpart = denominator / numerator;
- int fractpart = denominator % numerator;
- for(int x = 0, xe = 0, srcx = 0;x < linesize;x++) {
- accumulate(src, srcx, srcy, line[x], (numerator - xe) * weight);
- srcx++;
- for(int i = 0;i < intpart - 1;i++) {
- accumulate(src, srcx, srcy, line[x], numerator * weight);
- srcx++;
- }
- xe += fractpart;
- if(xe >= numerator) {
- xe -= numerator;
- srcx++;
- }
- accumulate(src, srcx, srcy, line[x], xe * weight);
- }
- }
-
- SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
- {
- if(numerator == denominator)
- {
- src->refcount++;
- return src;
- }
- else
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- int intpart = denominator / numerator;
- int fractpart = denominator % numerator;
- for(int y = 0, ye = 0, srcy = 0;y < dst->h;y++) {
- int line[dst->w][4];
- memset(line, 0, sizeof(int) * dst->w * 4);
- accumulate_line(src, srcy, line, dst->w, numerator - ye, numerator, denominator);
- srcy++;
- for(int i = 0;i < intpart - 1;i++) {
- accumulate_line(src, srcy, line, dst->w, numerator, numerator, denominator);
- srcy++;
- }
- ye += fractpart;
- if(ye >= numerator) {
- ye -= numerator;
- srcy++;
- }
- accumulate_line(src, srcy, line, dst->w, ye, numerator, denominator);
- for(int x = 0;x < dst->w;x++) {
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = SDL_MapRGBA(dst->format, line[x][0] / (denominator * denominator), line[x][1] / (denominator * denominator), line[x][2] / (denominator * denominator), line[x][3] / (denominator * denominator));
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }