mirror of
https://github.com/AppleWin/AppleWin.git
synced 2025-02-08 08:30:46 +00:00
WOZ: Support very large 5.25 WOZ images (#1240)
This commit is contained in:
parent
f8d238f2b0
commit
faff74a98d
@ -1505,13 +1505,22 @@ eDetectResult CWOZHelper::ProcessChunks(ImageInfo* pImageInfo, DWORD& dwOffset)
|
||||
m_pInfo = (InfoChunkv2*)pImage32;
|
||||
if (m_pInfo->v1.diskType != InfoChunk::diskType5_25)
|
||||
return eMismatch;
|
||||
#ifdef _DEBUG
|
||||
if (m_pInfo->v1.version >= 3)
|
||||
{
|
||||
InfoChunkv3* pInfoV3 = (InfoChunkv3*)pImage32;
|
||||
LogOutput("WOZ: Largest Flux Track = %d\n", pInfoV3->largestFluxTrack);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case TMAP_CHUNK_ID:
|
||||
pImageInfo->pWOZTrackMap = (BYTE*) pImage32;
|
||||
break;
|
||||
case TRKS_CHUNK_ID:
|
||||
dwOffset = pImageInfo->uOffset = pImageInfo->uImageSize - imageSizeRemaining; // offset into image of track data
|
||||
break;
|
||||
case FLUX_CHUNK_ID: // WOZ v3 (todo)
|
||||
break;
|
||||
case WRIT_CHUNK_ID: // WOZ v2 (optional)
|
||||
break;
|
||||
case META_CHUNK_ID: // (optional)
|
||||
@ -1574,14 +1583,29 @@ ImageError_e CImageHelperBase::CheckGZipFile(LPCTSTR pszImageFilename, ImageInfo
|
||||
if (hGZFile == NULL)
|
||||
return eIMAGE_ERROR_UNABLE_TO_OPEN_GZ;
|
||||
|
||||
const UINT MAX_UNCOMPRESSED_SIZE = GetMaxImageSize() + 1; // +1 to detect images that are too big
|
||||
pImageInfo->pImageBuffer = new BYTE[MAX_UNCOMPRESSED_SIZE];
|
||||
// determine uncompressed file length
|
||||
UINT fileSize = 0;
|
||||
{
|
||||
const UINT tempBufferSize = 256 * 1024;
|
||||
BYTE* tempBuffer = new BYTE[tempBufferSize];
|
||||
while (int len = gzread(hGZFile, tempBuffer, tempBufferSize))
|
||||
fileSize += len;
|
||||
delete[] tempBuffer;
|
||||
int res = gzrewind(hGZFile);
|
||||
if (res != 0)
|
||||
return eIMAGE_ERROR_GZ;
|
||||
}
|
||||
|
||||
int nLen = gzread(hGZFile, pImageInfo->pImageBuffer, MAX_UNCOMPRESSED_SIZE);
|
||||
if (fileSize == 0 || fileSize > GetMaxImageSize())
|
||||
return eIMAGE_ERROR_BAD_SIZE;
|
||||
|
||||
pImageInfo->pImageBuffer = new BYTE[fileSize];
|
||||
|
||||
int nLen = gzread(hGZFile, pImageInfo->pImageBuffer, fileSize);
|
||||
int nRes = gzclose(hGZFile); // close before returning (due to error) to avoid resource leak
|
||||
hGZFile = NULL;
|
||||
|
||||
if (nLen < 0 || nLen == MAX_UNCOMPRESSED_SIZE)
|
||||
if (nLen <= 0)
|
||||
return eIMAGE_ERROR_BAD_SIZE;
|
||||
|
||||
if (nRes != Z_OK)
|
||||
@ -1986,6 +2010,8 @@ bool CImageHelperBase::WOZUpdateInfo(ImageInfo* pImageInfo, DWORD& dwOffset)
|
||||
CDiskImageHelper::CDiskImageHelper(void) :
|
||||
CImageHelperBase(true)
|
||||
{
|
||||
m_vecImageTypes.push_back( new CWOZ1Image ); // Try to match WOZ1/WOZ2 first, as these can be precisely matched
|
||||
m_vecImageTypes.push_back( new CWOZ2Image );
|
||||
m_vecImageTypes.push_back( new CDoImage );
|
||||
m_vecImageTypes.push_back( new CPoImage );
|
||||
m_vecImageTypes.push_back( new CNib1Image );
|
||||
@ -1994,8 +2020,6 @@ CDiskImageHelper::CDiskImageHelper(void) :
|
||||
m_vecImageTypes.push_back( new CIIeImage );
|
||||
m_vecImageTypes.push_back( new CAplImage );
|
||||
m_vecImageTypes.push_back( new CPrgImage );
|
||||
m_vecImageTypes.push_back( new CWOZ1Image );
|
||||
m_vecImageTypes.push_back( new CWOZ2Image );
|
||||
}
|
||||
|
||||
CImageBase* CDiskImageHelper::Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, ImageInfo* pImageInfo)
|
||||
@ -2112,8 +2136,11 @@ CImageBase* CDiskImageHelper::GetImageForCreation(const TCHAR* pszExt, DWORD* pC
|
||||
|
||||
UINT CDiskImageHelper::GetMaxImageSize(void)
|
||||
{
|
||||
// TODO: This doesn't account for .2mg files with comments after the disk-image
|
||||
return UNIDISK35_800K_SIZE + m_MacBinaryHelper.GetMaxHdrSize() + m_2IMGHelper.GetMaxHdrSize();
|
||||
// Pathologic largest 5.25 image is a WOZ with FLUX tracks for each 0.25 track (GH#1240)
|
||||
const UINT largestFluxTrackInBlocks = 100; // typically this is 70-80 blocks
|
||||
const UINT maxTracks = 35 * 4; // typically only ~10-20 FLUX tracks (the rest TRKS tracks)
|
||||
const UINT bytesPerBlock = 512;
|
||||
return largestFluxTrackInBlocks * maxTracks * bytesPerBlock; // ~7MB
|
||||
}
|
||||
|
||||
UINT CDiskImageHelper::GetMinDetectSize(const UINT uImageSize, bool* pTempDetectBuffer)
|
||||
|
@ -284,6 +284,7 @@ private:
|
||||
static const UINT32 TRKS_CHUNK_ID = 'SKRT'; // 'TRKS'
|
||||
static const UINT32 WRIT_CHUNK_ID = 'TIRW'; // 'WRIT' - WOZv2
|
||||
static const UINT32 META_CHUNK_ID = 'ATEM'; // 'META'
|
||||
static const UINT32 FLUX_CHUNK_ID = 'XULF'; // 'FLUX' - WOZv3
|
||||
static const UINT32 INFO_CHUNK_SIZE = 60; // Fixed size for both WOZv1 & WOZv2
|
||||
|
||||
struct InfoChunk
|
||||
@ -314,6 +315,13 @@ private:
|
||||
static const BYTE optimalBitTiming5_25 = 32;
|
||||
};
|
||||
|
||||
struct InfoChunkv3
|
||||
{
|
||||
InfoChunkv2 v2;
|
||||
UINT16 fluxBlock; // Block number where the FLUX chuck resides relative to the start of the file.
|
||||
UINT16 largestFluxTrack; // in blocks (512 bytes)
|
||||
};
|
||||
|
||||
InfoChunkv2* m_pInfo; // NB. image-specific - only valid during Detect(), which calls InvalidateInfo() when done
|
||||
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user