Example #1
0
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;
}
Example #2
0
/**
 * 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;
}