#define WIN32_LEAN_AND_MEAN
#define NOWINRES
#define NOSERVICE
#define NOMCX
#define NOIME
#include "windows.h"
#include <stdio.h>
#include <malloc.h>
#define TAG_SIZE(a) (((a)[0]&0x7F)*0x200000 + ((a)[1]&0x7F)*0x4000 + ((a)[2]&0x7F)*0x80 + ((a)[3]&0x7F))
#define FME_SIZE(a) ((a)[0]*0x1000000 + (a)[1]*0x10000 + (a)[2]*0x100 + (a)[3])
#pragma pack(1)
struct ID3V2Header
{
BYTE Header[];
BYTE Version;
BYTE reVersion;
BYTE Flag;
BYTE Size[];
};
struct ID3V2Frame
{
BYTE FrameID[];
BYTE Size[];
BYTE Flag[];
};
#pragma pack()
BOOL WINAPI ExtractAlbum(const char *inputFile, const char *outputFile)
{
FILE *f = fopen(inputFile, "rb");
if (!f)
return FALSE;
BOOL success = FALSE;
ID3V2Header hdr;
if (fread(&hdr, sizeof(hdr), , f) != )
goto err;
if (memcmp(hdr.Header, "ID3", ))
goto err;
while (!feof(f))
{
if (ftell(f) - sizeof(hdr) >= TAG_SIZE(hdr.Size))
break;
ID3V2Frame frame;
if (fread(&frame, sizeof(frame), , f) != )
break;
if (!memcmp(frame.FrameID, "APIC", ))
{
size_t pos = ftell(f);
int ofs = fgetc(f) ? : ;
while (fgetc(f)) {}
fseek(f, ofs, SEEK_CUR);
size_t len = (pos + FME_SIZE(frame.Size)) - ftell(f);
void *buf = malloc(len);
if (fread(buf, len, , f) == )
{
FILE *fpic = fopen(outputFile, "wb");
if (fpic)
{
fwrite(buf, len, , fpic);
fclose(fpic);
success = TRUE;
}
}
free(buf);
continue;
}
fseek(f, FME_SIZE(frame.Size), SEEK_CUR);
}
err:
fclose(f);
return success;
}