1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
//===================================================================
// Fonctions de sauvegarde de fichier. Activer avec CIMAGE_SAVEFILE
//===================================================================
#if defined(CIMAGE_SAVEFILE)
// Sauvegarde de l'image sur disque avec le format demandé en paramètre
BOOL CImage::SaveFile(LPCTSTR szFileName, int nFormat, int nData1, int nData2)
{
if(!szFileName || !szFileName[0])
return FALSE;
if(!m_hDib)
return FALSE; // Pas d'image à sauver -> inutile de se fatiguer!!
if(nFormat>=IMG_FORMAT_END)
return FALSE; // Format inconnu au bataillon -> on rentre...
// Init du buffer de sauvegarde
if(!InitSaveBuffer())
return FALSE;
// Ouverture générale du fichier. Le handle est ensuite passé aux sous-fonctions
HANDLE hFile=CreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
BOOL bSuccess = FALSE;
// Procédure de sauvegarde en fonction du format demandé
switch(nFormat)
{
case IMG_FORMAT_BMPWIN:
bSuccess = SaveBMPWIN(hFile);
break;
case IMG_FORMAT_BMPOS2:
bSuccess = SaveBMPOS2(hFile);
break;
case IMG_FORMAT_RLE:
bSuccess = SaveRLE(hFile);
break;
case IMG_FORMAT_PCX:
bSuccess=SavePCX(hFile);
break;
case IMG_FORMAT_GIF:
bSuccess=SaveGIF(hFile);
break;
case IMG_FORMAT_JPEG:
#if defined(CIMAGE_USE_JPEG)
bSuccess = SaveJPEG(hFile, nData1);
#endif
break;
case IMG_FORMAT_TIFF:
#if defined(CIMAGE_USE_TIFF)
bSuccess = SaveTIFF(hFile, szFileName, nData1);
#endif
break;
case IMG_FORMAT_TGA:
bSuccess=SaveTGA(hFile, nData1);
// nData1 contient le type de compression à utiliser
break;
case IMG_FORMAT_PNG:
#if defined(CIMAGE_USE_PNG)
bSuccess = SavePNG(hFile);
#endif
break;
}
// Flush et destruction du buffer
if(!FlushSaveBuffer(hFile, bSuccess))
bSuccess=FALSE;
// Le type de format est remis à jour ici, pas dans les sous-fonctions
if(bSuccess)
m_nFileFormat = nFormat;
// Fermeture du fichier en cours
CloseHandle(hFile);
// Si la sauvegarde a échoué -> on supprime le fichier créé vide
if(!bSuccess)
DeleteFile(szFileName);
return bSuccess;
}
// Init du buffer de sauvegarde. Les fonctions de bufferisation permettent
// de limiter les accès disques et d'accelérer ainsi les sauvegardes
BOOL CImage::InitSaveBuffer()
{
// On vérifie que m_LoadBuffer n'est pas déjà utilisé
if(m_LoadBuffer)
return FALSE;
// Réserve de la mémoire avec taille standard de 10ko
if(!(m_LoadBuffer=malloc(SIZE_SAVE_BUFFER)))
return FALSE;
// OK -> on ramène TRUE
memset(m_LoadBuffer, 0, SIZE_SAVE_BUFFER);
m_dwSaveBufferLen = NULL;
return TRUE;
}
// Place des octets à sauver du disque dans le buffer. Si le buffer est
// plein, il est écrit sur disque et vidé
BOOL CImage::WriteSaveBuffer(HANDLE hFile, LPVOID Buffer, DWORD nLen)
{
// !! Ne jamais appeler cette fonction si m_LoadBuffer n'est pas valide
// !! Pour augmenter la rapidité, aucune vérification sur la validité
// des données n'est effectuée
// Copie des octets 1 à 1 dans le buffer
for(DWORD i=0; i<nLen; )
{
((BYTE*)m_LoadBuffer)[m_dwSaveBufferLen++]=((BYTE*)Buffer)[i++];
// Si on dépasse le buffer, on écrit et on vide
if(m_dwSaveBufferLen>=SIZE_SAVE_BUFFER)
{
DWORD dwByteWrite;
if(!WriteFile(hFile, m_LoadBuffer, m_dwSaveBufferLen,
&dwByteWrite, NULL)
|| dwByteWrite!=m_dwSaveBufferLen)
return FALSE;
memset(m_LoadBuffer, 0, SIZE_SAVE_BUFFER);
m_dwSaveBufferLen = NULL;
}
}
return TRUE;
}
// Force l'écriture des données sur disque et détruit le buffer
// Si bWrite==FALSE, seulement destruction, pas d'écriture
BOOL CImage::FlushSaveBuffer(HANDLE hFile, BOOL bWrite)
{
// Si buffer inexistant -> on rentre
if(!m_LoadBuffer)
return FALSE;
BOOL bSuccess = TRUE;
// Ecriture des données sur disque
if(bWrite && m_dwSaveBufferLen)
{
DWORD dwByteWrite;
if(!WriteFile(hFile, m_LoadBuffer, m_dwSaveBufferLen,
&dwByteWrite, NULL)
|| dwByteWrite!=m_dwSaveBufferLen)
bSuccess = FALSE;
}
// Destruction du buffer et sortie
free(m_LoadBuffer);
m_LoadBuffer=NULL;
return bSuccess;
} |