Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- typedef struct Header
- {
- unsigned char tag[3];
- unsigned char v1;
- unsigned char v2;
- unsigned char flags;
- unsigned char size[4];
- } mp3Header;
- unsigned char *formatFrameData(int size, unsigned char *data)
- {
- unsigned char *result;
- result = (unsigned char*)malloc(sizeof(unsigned char) * ((size-3)/2 + 1));
- int pos = 0;
- //pass 3 bytes and every NUL symbol
- for (int i = 3; i < size; i+=2)
- {
- *(result + pos) = *(data + i);
- pos++;
- }
- *(result + pos) = '\0';
- return result;
- }
- void printID3v2FrameInfo(unsigned char fid[5], int size, unsigned char *data)
- {
- printf("\n[%s]:\t%s\n", fid, formatFrameData(size, data));
- }
- typedef struct FrameHeader
- {
- unsigned char tag[4];
- unsigned char size[4];
- unsigned char flags[2];
- } id3v2Frame;
- unsigned char frames[77][5] = {
- "AENC",
- "APIC",
- "COMM",
- "COMR",
- "ENCR",
- "EQUA",
- "ETCO",
- "GEOB",
- "GRID",
- "IPLS",
- "LINK",
- "MCDI",
- "MLLT",
- "OWNE",
- "PRIV",
- "PCNT",
- "POPM",
- "POSS",
- "RBUF",
- "RVAD",
- "RVRB",
- "SYLT",
- "SYTC",
- "TALB",
- "TBPM",
- "TCMP",
- "TCOM",
- "TCON",
- "TCOP",
- "TDAT",
- "TDLY",
- "TENC",
- "TEXT",
- "TFLT",
- "TIME",
- "TIT1",
- "TIT2",
- "TIT3",
- "TKEY",
- "TLAN",
- "TLEN",
- "TMED",
- "TOAL",
- "TOFN",
- "TOLY",
- "TOPE",
- "TORY",
- "TOWN",
- "TPE1",
- "TPE2",
- "TPE3",
- "TPE4",
- "TPOS",
- "TPUB",
- "TRCK",
- "TRDA",
- "TRSN",
- "TRSO",
- "TSIZ",
- "TSO2",
- "TSOC",
- "TSRC",
- "TSSE",
- "TYER",
- "TXXX",
- "UFID",
- "USER",
- "USLT",
- "WCOM",
- "WCOP",
- "WOAF",
- "WOAR",
- "WOAS",
- "WORS",
- "WPAY",
- "WPUB",
- "WXXX"
- };
- int getHeaderSize(unsigned char size[4])
- {
- int c = 0;
- int res = 0;
- for (int i = 3; i >= 0; i--)
- {
- for (int j = 0; j < 7; j++)
- {
- res += (size[i] % 2) * pow(2, c);
- c++;
- size[i] /= 2;
- }
- }
- return res;
- }
- int getFrameSize(unsigned char size[4])
- {
- int res = 0;
- int c = 0;
- for (int i = 3; i >= 0; i--)
- {
- while (size[i])
- {
- res += (size[i] % 2) * pow(2, c);
- c++;
- size[i] /= 2;
- }
- }
- return res;
- }
- int checkFrame(char *frame)
- {
- int found = 0;
- for (int i = 0; i < 77; i++)
- {
- if (strcmp(frame, frames[i]) == 0)
- {
- found = 1;
- break;
- }
- }
- return found;
- }
- void getFrames(FILE *f, unsigned char *frame)
- {
- id3v2Frame newFrame;
- unsigned char *frameData;
- int success = 0;
- fread(&newFrame, 1, 10, f);
- int frameSize = getFrameSize(newFrame.size);
- while (checkFrame(newFrame.tag))
- {
- frameData = (unsigned char*)malloc(sizeof(unsigned char) * frameSize);
- fread(frameData, frameSize, 1, f);
- if (*frame == '\0' || strcmp(frame, newFrame.tag) == 0)
- {
- printID3v2FrameInfo(newFrame.tag, frameSize, frameData);
- success = 1;
- }
- fread(&newFrame, 1, 10, f);
- frameSize = getFrameSize(newFrame.size);
- }
- if (success == 0)
- printf("[ERROR] There's no such frame (%s).", frame);
- }
- unsigned char *formHeaderSize(int size)
- {
- unsigned char *cur;
- cur = (unsigned char*)malloc(sizeof(unsigned char) * 4);
- for (int i = 0; i < 4; i++)
- cur[i] = 0;
- unsigned char sz[32];
- int c = 0;
- for (int i = 0; i < 32; i++)
- sz[i] = '0';
- while (size)
- {
- sz[31 - c] = '0' + size % 2;
- c++;
- size /= 2;
- }
- for (int k = 3; k >= 0; k--)
- {
- c = 0;
- for (int i = (k == 3 ? (k + 1) * 8 - 1 : (k + 1) * 8); i > k * 8; i--)
- {
- cur[k] += (sz[i] - '0') * pow(2, c);
- c++;
- }
- }
- return cur;
- }
- unsigned char *updFrameData(unsigned char *in, int size)
- {
- unsigned char *out;
- out = (unsigned char*)malloc(sizeof(unsigned char) * (size * 2 + 3));
- *(out + 0) = 1;
- *(out + 1) = 255;
- *(out + 2) = 254;
- int pos = 3;
- for (int i = 0; i < size; i++)
- {
- *(out + pos) = *(in + i);
- pos++;
- *(out + pos) = 0;
- pos++;
- }
- return out;
- }
- unsigned char *formFrameSize(int size)
- {
- unsigned char *out;
- out = (unsigned char*)malloc(sizeof(unsigned char)*4);
- for (int i = 0; i < 4; i++)
- *(out + i) = 0;
- int c = 0;
- int k = 3;
- while(size)
- {
- *(out + k) += (size % 2) * pow(2, c);
- c++;
- size /= 2;
- if (c == 8)
- {
- c = 0;
- k--;
- }
- }
- return out;
- }
- void rewriteID3v2(FILE *f, unsigned char *frame, unsigned char *value, unsigned char *filename, long headersize, long filesize)
- {
- unsigned char **framesIDs;
- int *framesSizes;
- unsigned char **framesData;
- int sizeofNewHeader = 0;
- id3v2Frame newFrame;
- int c = 0;
- int ex = 0;
- fread(&newFrame, 1, 10, f);
- int frameSize = getFrameSize(newFrame.size);
- framesData = (unsigned char**)malloc(sizeof(unsigned char*) * 77);
- framesIDs = (unsigned char**)malloc(sizeof(unsigned char*) * 77);
- framesSizes = (int*)malloc(sizeof(int) * 77);
- while (checkFrame(newFrame.tag))
- {
- sizeofNewHeader += 10;
- if (strcmp(frame, newFrame.tag) == 0)
- {
- *(framesIDs + c) = (unsigned char*)malloc(sizeof(unsigned char) * 5);
- strcpy(*(framesIDs + c), newFrame.tag);
- *(framesSizes + c) = strlen(value) * 2 + 3;
- sizeofNewHeader += strlen(value) * 2 + 3;
- *(framesData + c) = (unsigned char*)malloc(sizeof(unsigned char) * (strlen(value)*2 + 3));
- unsigned char *formattedValue = updFrameData(value, strlen(value) * 2 + 3);
- for(int i = 0; i < strlen(value) * 2 + 3; i++)
- *(*(framesData + c) + i) = *(formattedValue + i);
- fseek(f, frameSize, SEEK_CUR);
- ex = 1;
- }
- else
- {
- *(framesIDs + c) = (unsigned char*)malloc(sizeof(unsigned char) * 5);
- strcpy(*(framesIDs + c), newFrame.tag);
- *(framesSizes + c) = frameSize;
- sizeofNewHeader += frameSize;
- *(framesData + c) = (unsigned char*)malloc(sizeof(unsigned char) * frameSize);
- fread(*(framesData + c), frameSize, 1, f);
- }
- fread(&newFrame, 1, 10, f);
- //printf("%s\n", newFrame.tag);
- frameSize = getFrameSize(newFrame.size);
- c++;
- }
- if (ex == 0)
- {
- *(framesIDs + c) = (unsigned char*)malloc(sizeof(unsigned char) * 5);
- strcpy(*(framesIDs + c), frame);
- *(framesSizes + c) = strlen(value) * 2 + 3;
- sizeofNewHeader += strlen(value) * 2 + 3 + 10;
- *(framesData + c) = (unsigned char*)malloc(sizeof(unsigned char) * (strlen(value)*2 + 3));
- unsigned char *formattedValue = updFrameData(value, strlen(value) * 2 + 3);
- for(int i = 0; i < strlen(value) * 2 + 3; i++)
- *(*(framesData + c) + i) = *(formattedValue + i);
- }
- unsigned char *new_file;
- new_file = (unsigned char*)malloc(sizeof(unsigned char) * (strlen(filename) + 5));
- char *fn = strtok(filename, ".");
- sprintf (new_file, "%s_new.mp3", fn);
- FILE *o = fopen(new_file, "wb");
- fwrite("ID3", 1, 3, o);
- unsigned char t[1] = {3};
- fwrite(t, 1, 1, o);
- t[0] = 0;
- fwrite(t, 1, 1, o);
- fwrite(t, 1, 1, o);
- fwrite(formHeaderSize(sizeofNewHeader), 1, 4, o);
- for (int i = 0; i <= (ex == 0 ? c : c - 1) ; i++)
- {
- fwrite(*(framesIDs + i), 1, 4, o);
- fwrite(formFrameSize(*(framesSizes + i)), 1, 4, o);
- fwrite(t, 1, 1, o);
- fwrite(t, 1, 1, o);
- fwrite(*(framesData + i), 1, *(framesSizes + i), o);
- }
- char *mp3;
- mp3 = (unsigned char*)malloc(sizeof(unsigned char) * filesize);
- fseek(f, headersize, SEEK_SET);
- fread(mp3, 1, filesize, f);
- fwrite(mp3, 1, filesize, o);
- fclose(o);
- }
- int main(int argc, unsigned char **argv)
- {
- unsigned char *val;
- unsigned char *filename;
- unsigned char *getFrame;
- unsigned char *setFrame;
- unsigned char *setFrameVal;
- int show = 0;
- int get = 0;
- int set = 0;
- for (int i = 1; i < argc; i++)
- {
- val = strtok(*(argv + i), "=");
- if (strcmp(val, "--filepath") == 0)
- {
- val = strtok(NULL, "=");
- filename = val;
- }
- else if (strcmp(val, "--get") == 0)
- {
- val = strtok(NULL, "=");
- getFrame = val;
- get = 1;
- }
- else if (strcmp(val, "--set") == 0)
- {
- val = strtok(NULL, "=");
- setFrame = val;
- set = 1;
- }
- else if (strcmp(val, "--value") == 0)
- {
- val = strtok(NULL, "=");
- setFrameVal = val;
- }
- else if (strcmp(val, "--show") == 0)
- {
- show = 1;
- }
- }
- FILE *f = fopen(filename, "rw");
- mp3Header header;
- fread(&header, 1, 10, f);
- if (show == 1)
- {
- getFrames(f, "");
- fclose(f);
- return 0;
- }
- if (get == 1)
- {
- getFrames(f, getFrame);
- fclose(f);
- return 0;
- }
- if (set == 1)
- {
- fseek(f, 0, SEEK_END);
- long f_size = ftell(f);
- fseek(f, 0, SEEK_SET);
- fread(&header, 1, 10, f);
- int hz = getHeaderSize(header.size);
- rewriteID3v2(f, setFrame, setFrameVal, filename, hz + 10, f_size - hz - 10);
- fclose(f);
- return 0;
- }
- return (0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement