#include "snes9x.h" #include #include #include "dxerr.h" #include "image_functions.h" #ifdef HAVE_LIBPNG bool loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, unsigned char **outData) { png_structp png_ptr; png_infop info_ptr; unsigned int sig_read = 0; int color_type, interlace_type; FILE *fp; if ((fp = _tfopen(name, TEXT("rb"))) == NULL) return false; /* Create and initialize the png_struct * with the desired error handler * functions. If you want to use the * default stderr and longjump method, * you can supply NULL for the last * three parameters. We also supply the * the compiler header file version, so * that we know if the application * was compiled with a compatible version * of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); return false; } /* Allocate/initialize the memory * for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return false; } /* Set error handling if you are * using the setjmp/longjmp method * (this is the normal method of * doing things with libpng). * REQUIRED unless you set up * your own error handlers in * the png_create_read_struct() * earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated * with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(fp); /* If we get here, we had a * problem reading the file */ return false; } /* Set up the output control if * you are using standard C streams */ png_init_io(png_ptr, fp); /* If we have already * read some of the signature */ png_set_sig_bytes(png_ptr, sig_read); /* * If you have enough memory to read * in the entire image at once, and * you need to specify only * transforms that can be controlled * with one of the PNG_TRANSFORM_* * bits (this presently excludes * dithering, filling, setting * background, and doing gamma * adjustment), then you can read the * entire image (including pixels) * into the info structure with this * call * * PNG_TRANSFORM_STRIP_16 | * PNG_TRANSFORM_PACKING forces 8 bit * PNG_TRANSFORM_EXPAND forces to * expand a palette into RGB */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, (png_voidp)NULL); outWidth = png_get_image_width(png_ptr, info_ptr); outHeight = png_get_image_height(png_ptr, info_ptr); switch (png_get_color_type(png_ptr, info_ptr)) { case PNG_COLOR_TYPE_RGBA: outHasAlpha = true; break; case PNG_COLOR_TYPE_RGB: outHasAlpha = false; break; default: png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); return false; } unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr); *outData = (unsigned char*)malloc(row_bytes * outHeight); png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr); for (int i = 0; i < outHeight; i++) { memcpy(*outData + (row_bytes * i), row_pointers[i], row_bytes); } /* Clean up after the read, * and free any memory allocated */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); /* Close the file */ fclose(fp); /* That's it */ return true; } #else bool loadPngImage(const TCHAR *name, int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData) { /* No PNG support */ return false; } #endif bool loadTGA(const TCHAR *filename, STGA& tgaFile) { FILE *file; unsigned char type[4]; unsigned char info[6]; file = _tfopen(filename, TEXT("rb")); if (!file) return false; fread(&type, sizeof(char), 3, file); fseek(file, 12, SEEK_SET); fread(&info, sizeof(char), 6, file); //image type either 2 (color) or 3 (greyscale) if (type[1] != 0 || (type[2] != 2 && type[2] != 3)) { fclose(file); return false; } tgaFile.width = info[0] + info[1] * 256; tgaFile.height = info[2] + info[3] * 256; tgaFile.byteCount = info[4] / 8; if (tgaFile.byteCount != 3 && tgaFile.byteCount != 4) { fclose(file); return false; } long imageSize = tgaFile.width * tgaFile.height * tgaFile.byteCount; //allocate memory for image data unsigned char *tempBuf = new unsigned char[imageSize]; tgaFile.data = new unsigned char[tgaFile.width * tgaFile.height * 4]; //read in image data fread(tempBuf, sizeof(unsigned char), imageSize, file); //swap line order and convert to RBGA for (int i = 0; iCreateTexture(width, height, 1, 0, hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, ppTexture, NULL); if (SUCCEEDED(hr)) { LPDIRECT3DTEXTURE9 pTexture = *ppTexture; D3DLOCKED_RECT lr; HRESULT hr; if (FAILED(hr = pTexture->LockRect(0, &lr, NULL, 0))) { pTexture->Release(); DXTRACE_ERR_MSGBOX(TEXT("Unable to lock texture"), hr); } else { memcpy(lr.pBits, bytes, lr.Pitch * height); pTexture->UnlockRect(0); ret = true; } } if (needFree) free(bytes); return ret; }