int res_create_theme_display_surface(const char* name, const char* themename, gr_surface* pSurface) {
    gr_surface surface = NULL;
    int result = 0;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_uint_32 width, height;
    png_byte channels;

    *pSurface = NULL;

    result = open_theme_png(name, themename, &png_ptr, &info_ptr, &width, &height, &channels);
    if (result < 0) return result;

    surface = init_display_surface(width, height);
    if (surface == NULL) {
        result = -8;
        goto exit;
    }

    unsigned char* p_row = malloc(width * 4);
    unsigned int y;
    for (y = 0; y < height; ++y) {
        png_read_row(png_ptr, p_row, NULL);
        transform_rgb_to_draw(p_row, surface->data + y * surface->row_bytes, channels, width);
    }
    free(p_row);

    *pSurface = surface;

    exit:
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    if (result < 0 && surface != NULL) free(surface);
    return result;
}
int
res_create_display_surface(const char *name, gr_surface *pSurface)
{
	int result = 0;
	unsigned int y;
	unsigned char *p_row;
	gr_surface surface = NULL;
	png_structp png_ptr = NULL;
	png_infop info_ptr = NULL;
	png_uint_32 width, height;
	png_byte channels;
	FILE *fp = NULL;

	*pSurface = NULL;

	result = open_png(name, &png_ptr, &info_ptr, &fp, &width, &height,
			  &channels);
	if (result < 0)
		return result;

	if (!(surface = init_display_surface(width, height))) {
		result = -8;
		goto exit;
	}

	/* TODO: check for error */
	p_row = malloc(width * 4);
	for (y = 0; y < height; y++) {
		png_read_row(png_ptr, p_row, NULL);
		transform_rgb_to_draw(p_row,
				      surface->data + y * surface->row_bytes,
				      channels, width);
	}

	free(p_row);

	*pSurface = surface;

exit:
	close_png(&png_ptr, &info_ptr, fp);
	if (result < 0 && surface != NULL)
		free(surface);

	return result;
}
예제 #3
0
int res_create_surface_png(const char* name, gr_surface* pSurface) {
    GGLSurface* surface = NULL;
    int result = 0;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_uint_32 width, height;
    png_byte channels;
    FILE* fp;

    *pSurface = NULL;

    result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels, &fp);
    if (result < 0) return result;

    surface = init_display_surface(width, height);
    if (surface == NULL) {
        result = -8;
        goto exit;
    }

    unsigned char* p_row = malloc(width * 4);
    unsigned int y;
    for (y = 0; y < height; ++y) {
        png_read_row(png_ptr, p_row, NULL);
        transform_rgb_to_draw(p_row, surface->data + y * width * 4, channels, width);
    }
    free(p_row);

    if (channels == 3)
        surface->format = GGL_PIXEL_FORMAT_RGBX_8888;
    else
        surface->format = GGL_PIXEL_FORMAT_RGBA_8888;

    *pSurface = (gr_surface) surface;

  exit:
    fclose(fp);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    if (result < 0 && surface != NULL) free(surface);
    return result;
}
예제 #4
0
// Scale image function
int res_scale_surface(gr_surface source, gr_surface* destination, float scale_w, float scale_h) {
    GGLContext *gl = NULL;
    GGLSurface* sc_mem_surface = NULL;
    *destination = NULL;
    GGLSurface *surface = (GGLSurface*)source;
    int w = gr_get_width(source), h = gr_get_height(source);
    int sx = 0, sy = 0, dx = 0, dy = 0;
    float dw = (float)w * scale_w;
    float dh = (float)h * scale_h;

    // Create a new surface that is the appropriate size
    sc_mem_surface = init_display_surface((int)dw, (int)dh);
    if (!sc_mem_surface) {
        printf("gr_scale_surface failed to init_display_surface\n");
        return -1;
    }
    sc_mem_surface->format = surface->format;

    // Initialize the context
    gglInit(&gl);
    gl->colorBuffer(gl, sc_mem_surface);
    gl->activeTexture(gl, 0);

    // Enable or disable blending based on source surface format
    if (surface->format == GGL_PIXEL_FORMAT_RGBX_8888) {
        gl->disable(gl, GGL_BLEND);
    } else {
        gl->enable(gl, GGL_BLEND);
        gl->blendFunc(gl, GGL_ONE, GGL_ZERO);
    }

    // Bind our source surface to the context
    gl->bindTexture(gl, surface);

    // Deal with the scaling
    gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MIN_FILTER, GGL_LINEAR);
    gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MAG_FILTER, GGL_LINEAR);
    gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
    gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
    gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
    gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
    gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
    gl->enable(gl, GGL_TEXTURE_2D);

    int32_t grad[8];
    memset(grad, 0, sizeof(grad));
    // s, dsdx, dsdy, scale, t, dtdx, dtdy, tscale   <- this is wrong!
    // This api uses block floating-point for S and T texture coordinates.
    // All values are given in 16.16, scaled by 'scale'. In other words,
    // set scale to 0, for 16.16 values.

    // s, dsdx, dsdy, t, dtdx, dtdy, sscale, tscale
    float dsdx = (float)w / dw;
    float dtdy = (float)h / dh;
    grad[0] = ((float)sx - (dsdx * dx)) * 65536;
    grad[1] = dsdx * 65536;
    grad[3] = ((float)sy - (dtdy * dy)) * 65536;
    grad[5] = dtdy * 65536;
//    printf("blit: w=%d h=%d dx=%d dy=%d dw=%f dh=%f dsdx=%f dtdy=%f s0=%x dsdx=%x t0=%x dtdy=%x\n",
//                    w,   h,    dx,   dy,   dw,   dh,   dsdx,   dtdy, grad[0], grad[1], grad[3], grad[5]);
    gl->texCoordGradScale8xv(gl, 0 /*tmu*/, grad);

    // draw / scale the source surface to our target context
    gl->recti(gl, dx, dy, dx + dw, dy + dh);
    gglUninit(gl);
    gl = NULL;
    // put the scaled surface in our destination
    *destination = (gr_surface*) sc_mem_surface;
    // free memory used in the source
    res_free_surface(source);
    source = NULL;
    return 0;
}
int res_create_theme_multi_display_surface(const char* name, const char* themename, int* frames, gr_surface** pSurface) {
    gr_surface* surface = NULL;
    int result = 0;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_uint_32 width, height;
    png_byte channels;
    int i;

    *pSurface = NULL;
    *frames = -1;

    result = open_theme_png(name, themename, &png_ptr, &info_ptr, &width, &height, &channels);
    if (result < 0) return result;

    *frames = 1;
    png_textp text;
    int num_text;
    if (png_get_text(png_ptr, info_ptr, &text, &num_text)) {
        for (i = 0; i < num_text; ++i) {
            if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
                *frames = atoi(text[i].text);
                break;
            }
        }
        printf("  found frames = %d\n", *frames);
    }

    if (height % *frames != 0) {
        printf("bad height (%d) for frame count (%d)\n", height, *frames);
        result = -9;
        goto exit;
    }

    surface = malloc(*frames * sizeof(gr_surface));
    if (surface == NULL) {
        result = -8;
        goto exit;
    }
    for (i = 0; i < *frames; ++i) {
        surface[i] = init_display_surface(width, height / *frames);
        if (surface[i] == NULL) {
            result = -8;
            goto exit;
        }
    }

    unsigned char* p_row = malloc(width * 4);
    unsigned int y;
    for (y = 0; y < height; ++y) {
        png_read_row(png_ptr, p_row, NULL);
        int frame = y % *frames;
        unsigned char* out_row = surface[frame]->data +
                                 (y / *frames) * surface[frame]->row_bytes;
        transform_rgb_to_draw(p_row, out_row, channels, width);
    }
    free(p_row);

    *pSurface = (gr_surface*) surface;

    exit:
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    if (result < 0) {
        if (surface) {
            for (i = 0; i < *frames; ++i) {
                if (surface[i]) free(surface[i]);
            }
            free(surface);
        }
    }
    return result;
}
int
res_create_multi_display_surface(const char *name, int *frames,
				 gr_surface **pSurface)
{
	int i, result = 0, num_text;
	unsigned int y;
	unsigned char *p_row;
	gr_surface *surface = NULL;
	png_structp png_ptr = NULL;
	png_infop info_ptr = NULL;
	png_uint_32 width, height;
	png_byte channels = 0;
	png_textp text;
	FILE *fp = NULL;

	*pSurface = NULL;
	*frames = -1;

	result = open_png(name, &png_ptr, &info_ptr, &fp, &width, &height,
			  &channels);
	if (result < 0)
		return result;

	*frames = 1;
	if (png_get_text(png_ptr, info_ptr, &text, &num_text)) {
		for (i = 0; i < num_text; i++)
			if (text[i].key && !strcmp(text[i].key, "Frames") &&
			    text[i].text) {
				*frames = atoi(text[i].text);
				break;
			}

		printf("  found frames = %d\n", *frames);
	}

	if (height % *frames != 0) {
		printf("bad height (%ld) for frame count (%d)\n",
		       (long)height, *frames);
		result = -9;
		goto exit;
	}

	if (!(surface = malloc(*frames * sizeof(gr_surface)))) {
		result = -8;
		goto exit;
	}

	for (i = 0; i < *frames; i++) {
		surface[i] = init_display_surface(width, height / *frames);
		if (!surface[i]) {
			result = -8;
			goto exit;
		}
	}

	/* TODO: Check for error */
	p_row = malloc(width * 4);
	for (y = 0; y < height; y++) {
		int frame = y % *frames;
		unsigned char *out_row;

		png_read_row(png_ptr, p_row, NULL);
		out_row = surface[frame]->data + (y / *frames) *
			  surface[frame]->row_bytes;
		transform_rgb_to_draw(p_row, out_row, channels, width);
	}

	free(p_row);

	*pSurface = (gr_surface *)surface;

exit:
	close_png(&png_ptr, &info_ptr, fp);

	if (result < 0)
		if (surface) {
			for (i = 0; i < *frames; i++)
				if (surface[i])
					free(surface[i]);

			free(surface);
		}

	return result;
}