int file_process(const char* file0, const char* file1, int opt_scale_x, int opt_scale_y, int opt_crc) { unsigned pixel; unsigned width; unsigned height; unsigned char* src_ptr; unsigned src_slice; unsigned char* dst_ptr; unsigned dst_slice; int type; int channel; png_color* palette; unsigned palette_size; if (file_read(file0, &src_ptr, &src_slice, &pixel, &width, &height, &type, &channel, &palette, &palette_size, 1) != 0) { goto err; } if (scale_precondition(opt_scale_x * 100 + opt_scale_y, pixel, width, height) != 0) { fprintf(stderr, "Error in the size of the source bitmap. Generally this happen\n"); fprintf(stderr, "when the bitmap is too small or when the width is not an exact\n"); fprintf(stderr, "multiplier of 8 bytes.\n"); goto err_src; } dst_slice = width * pixel * opt_scale_x; dst_ptr = malloc(dst_slice * height * opt_scale_y); if (!dst_ptr) { fprintf(stderr, "Low memory.\n"); goto err_src; } scale(opt_scale_x * 100 + opt_scale_y, dst_ptr, dst_slice, src_ptr, src_slice, pixel, width, height); if (file_write(file1, dst_ptr, dst_slice, pixel, width * opt_scale_x, height * opt_scale_y, type, channel, palette, palette_size) != 0) { goto err_dst; } if (opt_crc) { unsigned crc = crc32(0, dst_ptr, dst_slice * height * opt_scale_y); printf("%08x\n", crc); } free(dst_ptr); free(src_ptr); free(palette); return 0; err_dst: free(dst_ptr); err_src: free(src_ptr); free(palette); err: return -1; }
/** * Internal 8-bit Zoomer without smoothing. * Source code originally from SDL_gfx (LGPL) with permission by author. * * Zooms 8bit palette/Y 'src' surface to 'dst' surface. * Assumes src and dst surfaces are of 8-bit depth. * Assumes dst surface was allocated with the correct dimensions. * * @param src The surface to zoom (input). * @param dst The zoomed surface (output). * @param flipx Flag indicating if the image should be horizontally flipped. * @param flipy Flag indicating if the image should be vertically flipped. * @return 0 for success or -1 for error. */ int Zoom::_zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) { int x, y; static Uint32 *sax, *say; Uint32 *csax, *csay; int csx, csy; Uint8 *sp, *dp, *csp; int dgap; static bool proclaimed = false; if (Screen::is32bitEnabled()) { if (Options::useXBRZFilter) { // check the resolution to see which scale we need for (size_t factor = 2; factor <= 5; factor++) { if (dst->w == src->w * (int)factor && dst->h == src->h * (int)factor) { xbrz::scale(factor, (uint32_t*)src->pixels, (uint32_t*)dst->pixels, src->w, src->h, xbrz::RGB); return 0; } } } if (Options::useHQXFilter) { static bool initDone = false; if (!initDone) { hqxInit(); initDone = true; } // HQX_API void HQX_CALLCONV hq2x_32_rb( uint32_t * src, uint32_t src_rowBytes, uint32_t * dest, uint32_t dest_rowBytes, int width, int height ); if (dst->w == src->w * 2 && dst->h == src->h * 2) { hq2x_32_rb((uint32_t*)src->pixels, src->pitch, (uint32_t*)dst->pixels, dst->pitch, src->w, src->h); return 0; } if (dst->w == src->w * 3 && dst->h == src->h * 3) { hq3x_32_rb((uint32_t*)src->pixels, src->pitch, (uint32_t*)dst->pixels, dst->pitch, src->w, src->h); return 0; } if (dst->w == src->w * 4 && dst->h == src->h * 4) { hq4x_32_rb((uint32_t*)src->pixels, src->pitch, (uint32_t*)dst->pixels, dst->pitch, src->w, src->h); return 0; } } } if (Options::useScaleFilter) { // check the resolution to see which of scale2x, scale3x, etc. we need for (size_t factor = 2; factor <= 4; factor++) { if (dst->w == src->w * (int)factor && dst->h == src->h * (int)factor && !scale_precondition(factor, src->format->BytesPerPixel, src->w, src->h)) { scale(factor, dst->pixels, dst->pitch, src->pixels, src->pitch, src->format->BytesPerPixel, src->w, src->h); return 0; } } } // if we're scaling by a factor of 2 or 4, try to use a more efficient function /* if (src->format->BytesPerPixel == 1 && dst->format->BytesPerPixel == 1) { #ifdef __SSE2__ static bool _haveSSE2 = haveSSE2(); if (_haveSSE2 && !((ptrdiff_t)src->pixels % 16) && !((ptrdiff_t)dst->pixels % 16)) // alignment check { if (dst->w == src->w * 2 && dst->h == src->h * 2) return zoomSurface2X_SSE2(src, dst); else if (dst->w == src->w * 4 && dst->h == src->h * 4) return zoomSurface4X_SSE2(src, dst); } else { static bool complained = false; if (!complained) { complained = true; Log(LOG_ERROR) << "Misaligned surface buffers."; } } #endif // __WORDSIZE is defined on Linux, SIZE_MAX on Windows #if defined(__WORDSIZE) && (__WORDSIZE == 64) || defined(SIZE_MAX) && (SIZE_MAX > 0xFFFFFFFF) if (dst->w == src->w * 2 && dst->h == src->h * 2) return zoomSurface2X_64bit(src, dst); else if (dst->w == src->w * 4 && dst->h == src->h * 4) return zoomSurface4X_64bit(src, dst); #else if (sizeof(void *) == 8) { if (dst->w == src->w * 2 && dst->h == src->h * 2) return zoomSurface2X_64bit(src, dst); else if (dst->w == src->w * 4 && dst->h == src->h * 4) return zoomSurface4X_64bit(src, dst); } else { if (dst->w == src->w * 2 && dst->h == src->h * 2) return zoomSurface2X_32bit(src, dst); else if (dst->w == src->w * 4 && dst->h == src->h * 4) return zoomSurface4X_32bit(src, dst); } #endif // maybe X is scaled by 2 or 4 but not Y? if (dst->w == src->w * 4) return zoomSurface4X_XAxis_32bit(src, dst); else if (dst->w == src->w * 2) return zoomSurface2X_XAxis_32bit(src, dst); } */ if (!proclaimed) { Log(LOG_INFO) << "Using software scaling routine. For best results, try an OpenGL filter."; proclaimed = true; } /* * Allocate memory for row increments */ if ((sax = (Uint32 *) realloc(sax, (dst->w + 1) * sizeof(Uint32))) == NULL) { sax = 0; return (-1); } if ((say = (Uint32 *) realloc(say, (dst->h + 1) * sizeof(Uint32))) == NULL) { say = 0; //free(sax); return (-1); } /* * Pointer setup */ sp = csp = (Uint8 *) src->pixels; dp = (Uint8 *) dst->pixels; dgap = dst->pitch - dst->w; if (flipx) csp += (src->w-1); if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) ); /* * Precalculate row increments */ csx = 0; csax = sax; for (x = 0; x < dst->w; x++) { csx += src->w; *csax = 0; while (csx >= dst->w) { csx -= dst->w; (*csax)++; } (*csax) *= (flipx ? -1 : 1); csax++; } csy = 0; csay = say; for (y = 0; y < dst->h; y++) { csy += src->h; *csay = 0; while (csy >= dst->h) { csy -= dst->h; (*csay)++; } (*csay) *= src->pitch * (flipy ? -1 : 1); csay++; } /* * Draw */ csay = say; for (y = 0; y < dst->h; y++) { csax = sax; sp = csp; for (x = 0; x < dst->w; x++) { /* * Draw */ *dp = *sp; /* * Advance source pointers */ sp += (*csax); csax++; /* * Advance destination pointer */ dp++; } /* * Advance source pointer (for row) */ csp += (*csay); csay++; /* * Advance destination pointers */ dp += dgap; } /* * Never remove temp arrays */ //free(sax); //free(say); return 0; }