Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include "string.h"
- /*
- file structure:
- ID3v2/file identifier "ID3"
- ID3v2 version $03 00
- ID3v2 flags %abc00000
- ID3v2 size 4 * %0xxxxxxx
- Frame ID $xx xx xx xx (four characters)
- Size $xx xx xx xx
- Flags $xx xx
- <Frame contents>
- etc...
- */
- unsigned int bswap_32(unsigned int num){
- return ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | ((num >> 8) & 0xff00) | ((num << 24) & 0xff000000);
- }
- void filecopy(FILE *fp, FILE *ofp){
- int c;
- while ((c = getc(fp)) != EOF) putc(c, ofp);
- }
- union tag_header{
- char buffer[12];
- struct{
- unsigned short empty;
- unsigned char version[3];
- unsigned char rev1;
- unsigned char rev2;
- unsigned char flags;
- unsigned int size;
- } data;
- };
- union frame_header{
- char buffer[10];
- struct{
- unsigned char name[4];
- unsigned int size;
- unsigned short flags;
- } data;
- };
- void show(char* media_file_name){
- FILE* media_file = fopen(media_file_name, "rb");
- fseek(media_file, 0, SEEK_SET);
- union tag_header tag_header;
- fread(tag_header.buffer + 2, sizeof(char), 10, media_file);
- unsigned int tag_size = bswap_32(tag_header.data.size);
- printf("%sv%d.%d\n", tag_header.data.version, tag_header.data.rev1, tag_header.data.rev2);
- while (ftell(media_file) < tag_size + 10){
- union frame_header frame_header;
- fread(frame_header.buffer, sizeof(char), 10, media_file);
- printf("%s: ", frame_header.data.name);
- unsigned int frame_size = bswap_32(frame_header.data.size);
- unsigned char* frame_contents = malloc(sizeof(char) * frame_size);
- fread(frame_contents, sizeof(char), frame_size, media_file);
- for (unsigned int i = 0; i < frame_size; i++) printf("%c", frame_contents[i]);
- printf("\n");
- memset(frame_contents, 0, frame_size);
- free(frame_contents);
- }
- fclose(media_file);
- }
- void get(char* media_file_name, char sought_frame_name[4]){
- FILE* media_file = fopen(media_file_name, "rb");
- union tag_header tag_header;
- fread(tag_header.buffer + 2, sizeof(char), 10, media_file);
- unsigned int tag_size = bswap_32(tag_header.data.size);
- while (ftell(media_file) < tag_size + 10){
- union frame_header frame_header;
- fread(frame_header.buffer, sizeof(char), 10, media_file);
- long long current_frame_size = bswap_32(frame_header.data.size);
- if (!strcmp(frame_header.data.name, sought_frame_name)){
- printf("%s: ", frame_header.data.name);
- unsigned int frame_size = bswap_32(frame_header.data.size);
- unsigned char* frame_contents = malloc(sizeof(char) * frame_size);
- fread(frame_contents, sizeof(char), frame_size, media_file);
- for (unsigned int i = 0; i < frame_size; i++) printf("%c", frame_contents[i]);
- printf("\n");
- free(frame_contents);
- fclose(media_file);
- return;
- }
- fseek(media_file, current_frame_size, SEEK_CUR);
- }
- fclose(media_file);
- printf("No value found for %s!\n", sought_frame_name);
- }
- void set(char* media_file_name, char new_frame_name[4], char* new_frame_value){
- FILE* media_file = fopen(media_file_name, "rb");
- union tag_header tag_header;
- fread(tag_header.buffer + 2, sizeof(char), 10, media_file);
- unsigned int tag_size = bswap_32(tag_header.data.size);
- long long frame_to_change_pos = 0, frame_to_change_size = 0;
- while (ftell(media_file) < tag_size + 10){
- union frame_header frame_header;
- fread(frame_header.buffer, sizeof(char), 10, media_file);
- long long current_frame_size = bswap_32(frame_header.data.size);
- if (!strcmp(frame_header.data.name, new_frame_name)){
- frame_to_change_pos = ftell(media_file) - 10;
- frame_to_change_size = current_frame_size;
- break;
- }
- fseek(media_file, current_frame_size, SEEK_CUR);
- }
- if (frame_to_change_pos == 0) frame_to_change_pos = ftell(media_file);
- unsigned int new_value_size = strlen(new_frame_value);
- unsigned int new_tag_size = tag_size - frame_to_change_size + new_value_size;
- if (new_value_size == 0) new_tag_size -= 10;
- char* media_file_copy_name;
- media_file_copy_name = "temp.mp3";
- FILE* media_file_copy = fopen(media_file_copy_name, "wb");
- fseek(media_file, 0, SEEK_SET);
- fseek(media_file_copy, 0, SEEK_SET);
- filecopy(media_file, media_file_copy);
- fclose(media_file_copy);
- fclose(media_file);
- media_file_copy = fopen(media_file_copy_name, "rb");
- media_file = fopen(media_file_name, "wb");
- tag_header.data.size = bswap_32(new_tag_size);
- fwrite(tag_header.buffer + 2, sizeof(char), 10, media_file);
- fseek(media_file_copy, 10, SEEK_SET);
- for(unsigned long long i = 0; i < frame_to_change_pos - 10; i++){
- int c;
- c = getc(media_file_copy);
- putc(c, media_file);
- }
- if (new_value_size){
- union frame_header frame_header;
- frame_header.data.name[0] = new_frame_name[0];
- frame_header.data.name[1] = new_frame_name[1];
- frame_header.data.name[2] = new_frame_name[2];
- frame_header.data.name[3] = new_frame_name[3];
- frame_header.data.size = bswap_32(new_value_size);
- frame_header.data.flags = 0;
- fwrite(frame_header.buffer, sizeof(char), 10, media_file);
- }
- fwrite(new_frame_value, sizeof(char), new_value_size, media_file);
- fseek(media_file_copy, frame_to_change_pos + 10 + frame_to_change_size , SEEK_SET);
- for(unsigned long long i = ftell(media_file); i < new_tag_size; i++){
- unsigned short int c;
- c = getc(media_file_copy);
- putc(c, media_file);
- }
- printf("Frame set: %s -> \"%s\"\n", new_frame_name, new_frame_value);
- filecopy(media_file_copy, media_file);
- fclose(media_file);
- fclose(media_file_copy);
- remove(media_file_copy_name);
- }
- int main(int argc, char* argv[]){
- char* filepath;
- filepath = strpbrk(argv[1],"=") + 1;
- for (int i = 2;i < argc; i++){
- if (!strcmp(argv[i], "--show")){
- show(filepath);
- continue;
- }
- if (argv[i][2]=='g'){
- get(filepath, strpbrk(argv[i],"=") + 1);
- continue;
- }
- if (argv[i][2]=='s'){
- set(filepath, strpbrk(argv[i],"=") + 1, strpbrk(argv[i + 1], "=") + 1);
- continue;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement