int LCUI_ReadImageFile(const char *filepath, LCUI_Graph *out) { int ret; FILE *fp; LCUI_ImageReaderRec reader = { 0 }; fp = fopen(filepath, "rb"); if (!fp) { return -ENOENT; } ret = DetectImageType(filepath); LCUI_SetImageReaderForFile(&reader, fp); if (ret >= 0) { ret = LCUI_InitImageReaderByType(&reader, ret); } if (ret < 0) { if (LCUI_InitImageReader(&reader) != 0) { fclose(fp); return -2; } } if (LCUI_SetImageReaderJump(&reader)) { ret = -2; } else { ret = LCUI_ReadImage(&reader, out); } LCUI_DestroyImageReader(&reader); fclose(fp); return ret; }
int LCUI_GetImageSize(const char *filepath, int *width, int *height) { int ret; FILE *fp; LCUI_ImageReaderRec reader = { 0 }; fp = fopen(filepath, "rb"); if (!fp) { return -ENOENT; } ret = DetectImageType(filepath); LCUI_SetImageReaderForFile(&reader, fp); if (ret >= 0) { ret = LCUI_InitImageReaderByType(&reader, ret); } if (ret < 0) { if (LCUI_InitImageReader(&reader) != 0) { fclose(fp); return -2; } } *width = reader.header.width; *height = reader.header.height; LCUI_DestroyImageReader(&reader); fclose(fp); return 0; }
// External functions struct IsoFile *IsoFileOpenForRead(const char *filename) { struct IsoFile *newfile; int retval; int i; char tempblock[2448]; struct tocTN toctn; struct tocTD toctd; // union { // struct ECMA119PrimaryVolume vol; // char ch[sizeof(struct ECMA119PrimaryVolume)]; // } *volcheck; union { struct ECMA119PrimaryVolume *vol; char *ch; } volcheck; newfile = NULL; if (filename == NULL) return(NULL); #ifdef VERBOSE_FUNCTION_ISOFILE PrintLog("CDVD isofile: IsoFileOpenForRead(%s)", filename); #endif /* VERBOSE_FUNCTION_ISOFILE */ newfile = (struct IsoFile *) malloc(sizeof(struct IsoFile)); if (newfile == NULL) return(NULL); newfile->sectorpos = 0; newfile->openforread = 1; // Read-only ISO newfile->filebytepos = 0; newfile->filesectorpos = 0; newfile->blocksize = 0; // Flags as non-detected yet (Compress vs. Image) newfile->tabledata = NULL; newfile->namepos = 0; while ((newfile->namepos < 255) && (*(filename + newfile->namepos) != 0)) { newfile->name[newfile->namepos] = *(filename + newfile->namepos); newfile->namepos++; } // ENDWHILE- copying the file name in... newfile->name[newfile->namepos] = 0; // And 0-terminate. IsoNameStripExt(newfile); // Ex: -I00.Z[.bin] // File Compression name detection newfile->compress = IsoNameStripCompress(newfile); // Ex: -I00.bin[.Z] newfile->compresspos = newfile->namepos; // Test File name compression retval = -1; if (newfile->compress > 0) { retval = CompressOpenForRead(newfile); if (retval == -1) CompressClose(newfile); } // ENDIF- Have a compression type hint? Test it out if (retval == -1) { newfile->compress = 5; while ((newfile->compress > 0) && (retval == -1)) { retval = CompressOpenForRead(newfile); if (retval == -1) { CompressClose(newfile); newfile->compress--; } // ENDIF- Failed to open? Close it... and try the next one. } // ENDWHILE- Trying to find a compression scheme that will work... if (newfile->compress == 0) { newfile->handle = ActualFileOpenForRead(newfile->name); if (newfile->handle == ACTUALHANDLENULL) { free(newfile); newfile = NULL; return(NULL); } // ENDIF- Failed to open? Abort. newfile->filebytesize = ActualFileSize(newfile->handle); } // ENDIF- No compression? Open it uncompressed. } // ENDIF- Temp- failed to open? Abort... // Compressed data file with no table? Return prematurely... // Condition detection: compress > 0, tablehandle == ACTUALHANDLENULL if (retval == -2) { #ifdef VERBOSE_FUNCTION_ISOFILE PrintLog("CDVD isofile: Data file with no table!"); #endif /* VERBOSE_FUNCTION_ISOFILE */ return(newfile); } // ENDIF- newfile->imagetype = DetectImageType(newfile); if (newfile->compress == 0) { newfile->filesectorsize = newfile->filebytesize / newfile->blocksize; } // ENDIF- Now that blocksize is known, raw file sectors can be figured out IsoNameStripExt(newfile); // Ex: -I00[.bin].Z IsoNameStripMulti(newfile); // Ex: [-I00].bin.Z #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Filename: %s", filename); if (newfile->multi > 0) PrintLog("CDVD isofile: Multiple <2GB files."); PrintLog("CDVD isofile: Compression Method: %s", compressdesc[newfile->compress]); PrintLog("CDVD isofile: Image Type: %s", newfile->imagename); PrintLog("CDVD isofile: Block Size: %lli", newfile->blocksize); PrintLog("CDVD isofile: Total Sectors (of first file): %lli", newfile->filesectorsize); #endif /* VERBOSE_DISC_INFO */ // Load a TOC from a .toc file (is there is one) retval = IsoLoadTOC(newfile); if (retval == 0) return(newfile); // Get the volume sector for disc type test retval = IsoFileSeek(newfile, 16); if (retval < 0) { newfile = IsoFileClose(newfile); return(NULL); } // ENDIF- Could not find the directory sector? Abort. retval = IsoFileRead(newfile, tempblock); if (retval < 0) { newfile = IsoFileClose(newfile); return(NULL); } // ENDIF- Could not read the directory sector? Abort. volcheck.ch = tempblock; volcheck.ch += newfile->blockoffset; if (ValidateECMA119PrimaryVolume(volcheck.vol) != 0) { #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Not an ISO9660 disc! Music CD perhaps?"); #endif /* VERBOSE_DISC_INFO */ newfile->cdvdtype = CDVD_TYPE_CDDA; } else { // Is this a playstation image? i = 0; while ((*(playstationid + i) != 0) && (*(playstationid + i) == tempblock[newfile->blockoffset + 8 + i])) i++; if (*(playstationid + i) != 0) { #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Not a Playstation Disc!"); #endif /* VERBOSE_DISC_INFO */ newfile->cdvdtype = CDVD_TYPE_DVDV; } else { newfile->cdvdtype = CDVD_TYPE_PS2DVD; } // ENDIF- Is this not a Playstation 1 image? // Sidenote: if the emulator is just playing Playstation 2 images, we could // just invalidate the image file right here. } // ENDIF- Not an ISO9660 disc? Assume Music CD. if (newfile->cdvdtype == CDVD_TYPE_PS2DVD) { // Is this a Playstation CD image? i = 0; while ((*(cdname + i) != 0) && (*(cdname + i) == tempblock[newfile->blockoffset + 1024 + i])) i++; if (*(cdname + i) == 0) { newfile->cdvdtype = CDVD_TYPE_PSCD; #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Image is a Playstation 1 CD."); #endif /* VERBOSE_DISC_INFO */ } else { if (newfile->blocksize != 2048) { newfile->cdvdtype = CDVD_TYPE_PS2CD; #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Image is a Playstation 2 CD."); #endif /* VERBOSE_DISC_INFO */ } else { #ifdef VERBOSE_DISC_INFO PrintLog("CDVD isofile: Image is a DVD."); #endif /* VERBOSE_DISC_INFO */ } // ENDIF- Is the blocksize not 2048? CD image then. } // ENDIF- Is this a PS1 CD image? } // ENDIF- Is this a Playstation image? volcheck.ch = NULL; if ((newfile->cdvdtype == CDVD_TYPE_DVDV) && (newfile->blocksize == 2352)) newfile->cdvdtype = CDVD_TYPE_CDDA; // Slap together a TOC based on the above guesswork. IsoInitTOC(newfile); if ((newfile->cdvdtype != CDVD_TYPE_PS2DVD) && (newfile->cdvdtype != CDVD_TYPE_DVDV)) { toctn.strack = 1; toctn.etrack = 1; IsoAddTNToTOC(newfile, toctn); toctd.type = 0; toctd.lsn = newfile->filesectorsize; IsoAddTDToTOC(newfile, 0xAA, toctd); toctd.type = 0; // ? if (newfile->cdvdtype == CDVD_TYPE_CDDA) { toctd.type = CDVD_AUDIO_TRACK; // Music track assumed } else { toctd.type = CDVD_MODE1_TRACK; // Data track assumed } // ENDIF- Is this track a music or data track? toctd.lsn = 0; IsoAddTDToTOC(newfile, 1, toctd); } // ENDIF- Is this a CD? Single track for all sectors return(newfile); } // END IsoFileOpenForRead()