1 #define WIN32_LEAN_AND_MEAN 2 #define NOWINRES 3 #define NOSERVICE 4 #define NOMCX 5 #define NOIME 6 #include "windows.h" 7 8 #include <stdio.h> 9 #include <malloc.h> 10 11 #define TAG_SIZE(a) (((a)[0]&0x7F)*0x200000 + ((a)[1]&0x7F)*0x4000 + ((a)[2]&0x7F)*0x80 + ((a)[3]&0x7F)) 12 #define FME_SIZE(a) ((a)[0]*0x1000000 + (a)[1]*0x10000 + (a)[2]*0x100 + (a)[3]) 13 14 #pragma pack(1) 15 16 struct ID3V2Header 17 { 18 BYTE Header[3]; 19 BYTE Version; 20 BYTE reVersion; 21 BYTE Flag; 22 BYTE Size[4]; 23 }; 24 25 struct ID3V2Frame 26 { 27 BYTE FrameID[4]; 28 BYTE Size[4]; 29 BYTE Flag[2]; 30 }; 31 32 #pragma pack() 33 34 BOOL WINAPI ExtractAlbum(const char *inputFile, const char *outputFile) 35 { 36 FILE *f = fopen(inputFile, "rb"); 37 38 if (!f) 39 return FALSE; 40 41 BOOL success = FALSE; 42 43 ID3V2Header hdr; 44 45 if (fread(&hdr, sizeof(hdr), 1, f) != 1) 46 goto err; 47 48 if (memcmp(hdr.Header, "ID3", 3)) 49 goto err; 50 51 while (!feof(f)) 52 { 53 if (ftell(f) - sizeof(hdr) >= TAG_SIZE(hdr.Size)) 54 break; 55 56 ID3V2Frame frame; 57 58 if (fread(&frame, sizeof(frame), 1, f) != 1) 59 break; 60 61 if (!memcmp(frame.FrameID, "APIC", 4)) 62 { 63 size_t pos = ftell(f); 64 65 int ofs = fgetc(f) ? 7 : 2; 66 67 while (fgetc(f)) {} 68 69 fseek(f, ofs, SEEK_CUR); 70 71 size_t len = (pos + FME_SIZE(frame.Size)) - ftell(f); 72 73 void *buf = malloc(len); 74 75 if (fread(buf, len, 1, f) == 1) 76 { 77 FILE *fpic = fopen(outputFile, "wb"); 78 79 if (fpic) 80 { 81 fwrite(buf, len, 1, fpic); 82 fclose(fpic); 83 84 success = TRUE; 85 } 86 } 87 88 free(buf); 89 90 continue; 91 } 92 93 fseek(f, FME_SIZE(frame.Size), SEEK_CUR); 94 } 95 96 err: 97 fclose(f); 98 99 return success; 100 }