-2

I am reading H.264 bitstream as Hex file in c++. I want to insert some string whenever some certain condition met.
enter image description here
Like in the attached image if hex value of 00 00 00 01 occurs anywhere in the file i want to add some string like ABC before 00 00 00 01 in the file and save this as a new file. Write now my approach is to read h.264 file as hex. convert it into string and make a string comparison. if there is a way i can do a straight hex comparison? Here is my current code

 #include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
unsigned char x;
string s1,s2,s3;
s2="Mushahid Hussain";
s3="0000000141";
std::ifstream input("d:\\Jm\\videos\\trying2.264", std::ios::binary);
input >> std::noskipws;
while (input >> x) {
    long constant = 0x0000000168;
    std::ostringstream buffer; 

    buffer << std::hex << std::setw(2) << std::setfill('0')
            << (int)x;
    s1=buffer.str();
    if (s1.find(s1) != std::string::npos) {
        cout<<"hello";
    s1+=s2;
}
std::ofstream outfile;

  outfile.open("d:\\Jm\\bin\\trying5.264", std::ios_base::app);
  outfile << s1;

}

    return 0;
}


Edit 1
As answered by Tommylee2k i am able to append string . But problem is that at the end of file hex CD value is appending like shown in the attached image. enter image description here

Mushahid Hussain
  • 4,052
  • 11
  • 43
  • 62
  • _`while (input >> x) {`_ You want to read binary content, but actually refer to text formatted input. Rather use `std::istream::read()` to retrieve binary content of files. – πάντα ῥεῖ Jan 12 '16 at 19:06
  • @πάνταῥεῖ but that won't read file as a hex i guess. The file h.264 bit stream so i want read it as a hex file. – Mushahid Hussain Jan 12 '16 at 19:09
  • So you actually have ASCII coded hex values in that file? _"h.264 bit stream"_'s usually aren't encoded like this, but just contain pure binary data. – πάντα ῥεῖ Jan 12 '16 at 19:11
  • @πάνταῥεῖ The file is encoded video file. If i view it in Hex editor it shows like in the attached image. So i read this file as Hex in c++ and want to do some manipulations based on some conditions. – Mushahid Hussain Jan 12 '16 at 19:14
  • 1
    _`while (input >> x) {`_ Neither reads from _hex values_ (would require the `hex` I/O manipulator), nor from textual representation of the data. – πάντα ῥεῖ Jan 12 '16 at 19:17
  • @πάνταῥεῖ its working on my side. i got this code from here http://stackoverflow.com/questions/16410362/c-read-dat-file-as-hex-using-ifstream – Mushahid Hussain Jan 12 '16 at 19:24
  • Are you sure the formats are the same? I doubt so, what you refer to is the view of a hex file editor, representing the binary data in that specific format. – πάντα ῥεῖ Jan 12 '16 at 19:28
  • @πάνταῥεῖ Yeah you are right. Although its showing Hex representation file but not in that format which i want. Kindly guide me how can i achieve this? – Mushahid Hussain Jan 12 '16 at 19:32

1 Answers1

1

perhaps a better approach is to read the file binary into a memory buffer, and find the memcmp() instead. When you found your pattern, you write the block ahead of the match, then your "ABC"-string, and continue searching the rest of the file

#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>

char pattern[4]= { 0x00,0x00,0x01,0x67 };

char *memfind(char *s, int len, char *p, int plen) {
    int n=0;
    char *pos = s;
    while ((pos-s)<(len-plen)) {
        while ( *(pos+n) == *(p+n) && n<=plen) n++;
        if (n==plen) 
            return pos;
        pos++;n=0;
    }
    return NULL;
}

int main() {
    FILE *in = fopen("in.vid", "r+");
    FILE *out = fopen("out.vid", "wb");

    // get Filesize
    size_t size = 0;
    fseek(in, 0L, SEEK_END);
    size = ftell(in);

    // read whole file in
    char *buffer = malloc(size);
    fseek (in, 0L, SEEK_SET);
    fread (buffer, size, 1, in);

    char *currentPos = buffer;
    char *found;
    if (buffer) {
        while (1) {
            found = memfind(currentPos, size-(currentPos-buffer), pattern, sizeof(pattern));
            if (found==NULL) break;
            fwrite(currentPos, 1, (size_t) (found-currentPos), out);
            fwrite("ABC", sizeof("ABC"), 1, out);
            fwrite(pattern, sizeof(pattern),1,out);
            currentPos=found+4;
        }
        fwrite (currentPos, 1, (size_t) size - (currentPos-buffer), out);
        free(buffer);
    }
    fclose (in);
    fclose (out);

    return 0;
}
Tommylee2k
  • 2,683
  • 1
  • 9
  • 22
  • there is no "find" for memory like strstr, so I had to write it myself – Tommylee2k Jan 27 '16 at 11:14
  • +1 . Very much thanks for the answer. I am able to append string but having some some problem after executing your code. Kindly look at the updated question. Thanks – Mushahid Hussain Jan 27 '16 at 16:04
  • And also how to compare multiple patterns? – Mushahid Hussain Jan 28 '16 at 17:11
  • ah yes. my fault, ... at the end, when writing the trailing part of in.vid, there's too many bytes written. it has to be "size - (currentPos-buffer)" instead of " size - (buffer - currentPos)" Comparing multiple patterns would easiest be done with several runs, on each run you replace on pattern ... otherwise you'd have to have a "find whatever pattern comes first" search method – Tommylee2k Jan 29 '16 at 11:11
  • Sorry to bother you again.But i have tested the code and problem is still there. Its still appending hex value CD at the end of file. Its not actually end of file but file1 still not fully copied to file2 but it start appending CD as shown if figure as well. – Mushahid Hussain Jan 31 '16 at 15:47