1

I am trying to write some 2D coordinates into a binary file. However, what I read from the file that had been writen is quite different from the original data. Details are given here.

For example, I have 45 (X,Y) points. Both X and Y are integral number less than 600. The simulation requires store each of them with two bytes (8 bits) and 2 upper bits of each byte is reserved (for X, the reserved bits are filled by .mrk which is 1 or 2; for Y, simply use 0 instead). In this case, 14 bits binary number is able to represent the maximum, 16383. I write the data in several ways:

in_tmp is structure consisted of points number (.nm), points reserved mark (.mrk) and points coordinates (.coor)

for i=1:in_tmp.nm
    x1 = dec2bin(in_tmp.coor(i,1));
    y1 = dec2bin(in_tmp.coor(i,2));
      t1 = in_tm.mrk(i);
      if(t1==1)
          t2 = '01';
          t2b = 1;
      elseif(t1==2)
          t2 = '10';
          t2b = 2;
      end
      lenx = 16-length(x1);
      leny = 16-length(y1);
      x1hl = strcat(t2, '00000000000000');   % High and low
      y1hl = '0000000000000000';
      x1a = strcat(x1hl(1:lenx), num2str(x1));
      y1a = strcat(y1hl(1:leny), num2str(y1));
      y1a(1:2) = '00';
%     x1b = in_tmp.coor(i,1);
%     y1b = in_tmp.coor(i,2);
%     fwrite(fp1, t2b, 'ubit2');
%     fwrite(fp1, x1b, 'ubit14');
%     
%     fwrite(fp1, 0, 'ubit2');
%     fwrite(fp1, y1b, 'ubit14');
      fwrite(fp1, bin2dec(x1a), 'uint16');
      fwrite(fp1, bin2dec(y1a), 'uint16');
%     fwrite(fp1, bin2dec(x1a(1:8)), 'uint8');
%     fwrite(fp1, bin2dec(x1a(9:end)), 'uint8');
%     fwrite(fp1, bin2dec(y1a(1:8)), 'uint8');
%     fwrite(fp1, bin2dec(y1a(9:end)), 'uint8');
%     x1c = in_tmp.coor(i,1);
%     y1c = in_tmp.coor(i,2);
%     
%     x1hex = dec2hex(x1c);
%     y1hex = dec2hex(y1c);
%     if(length(x1hex)>2)
%         x1h = x1hex(1:end-2);
%         x1l = x1hex(end-1:end);
%     else
%         x1h = dec2hex(0);
%         x1l = x1hex;
%     end
%     
%     tx1h = dec2bin(hex2dec(x1h));
%     l1 = length(tx1h);
%     bin0 = dec2bin(128);    % '10000000'
%     if(t1==1)
%         bin0(end-l1+1:end) = tx1h;
%         bin0(1)=0;
%         bin0(2)=1;
%         
%     elseif(t1==2)
%         bin0(end-l1+1:end) = tx1h;
%     end
%     x1h = bin2dec(tx1h);
%     
%         if(length(y1hex)>2)
%         y1h = y1hex(1:end-2);
%         y1l = y1hex(end-1:end);
%     else
%         y1h = dec2hex(0);
%         y1l = y1hex;
%     end
%     fwrite(fp1, x1h, 'uint8');
%     fwrite(fp1, hex2dec(x1l), 'uint8');
%     fwrite(fp1, hex2dec(y1h), 'uint8');
%     fwrite(fp1, hex2dec(y1l), 'uint8');
end

The way I read it

    for i=1:mt.nm              % nm points.
        mred(i,6) = fread(fp1, 1, 'uint8');       % Raw X coordinates.
        mred(i,7) = fread(fp1, 1, 'uint8');       % upper 2 bits are reserved info.
        tmpx = [dec2bin(mred(i,6)), dec2bin(mred(i,7))];
        if(length(tmpx)==16)
            mred(i,4) = bin2dec(tmpx(1:2));       % Real Mark.
            mred(i,1) = bin2dec(tmpx(3:end));     % Real X.
        elseif(length(tmpx)==15)
            mred(i,4) = bin2dec(tmpx(1));         % Real Type.
            mred(i,1) = bin2dec(tmpx(2:end));     % Real X.
        else
            mred(i,4) = bin2dec(tmpx(1:2));       % Type unknown.
            mred(i,1) = bin2dec(tmpx(3:end));     % Real X.
        end       
          mred(i,8) = fread(fp1, 1, 'uint8');       % Y coordinates.
          mred(i,9) = fread(fp1, 1, 'uint8');       % upper 2 bits are reserved.
          tmpy = [dec2bin(mred(i,8)), dec2bin(mred(i,9))];
          if(length(tmpy)==16)
              mred(i,10) = bin2dec(tmpy(1:2));      % Real reserved.
              mred(i,2) = bin2dec(tmpy(3:end));     % Real Y.
          elseif(length(tmpy)==15)
              mred(i,10) = bin2dec(tmpy(1));        % Real reserved.
              mred(i,2) = bin2dec(tmpy(2:end));     % Real Y.
          else
              mred(i,10) = -1;                      % Reserved unknown.
              mred(i,2) = bin2dec(tmpy);            % Real Y.
          end               
    end

The read() function works well for a given software which is implemented via C++. The software generates coordinates series in such a format. Then, I prepare a read() to get the information in the binary file generated by C++ software. Then, I want to implement the write() with Matlab in that format, but the read() fails to obtain what I had written to the binary file. Anybody help? Thanks.

4
  • How does it fail? No data? Wrong data? Errors out? Commented Feb 24, 2015 at 16:08
  • Is reading/writing on the same machine (architecture)? You may have an endian-ness problem. Commented Feb 24, 2015 at 17:36
  • @excaza Wrong data in comparing with what I written to the file (original data). Commented Feb 25, 2015 at 10:02
  • @TryHard Actually, I implemented the read function to get data from the binary file generated by the software. It works perfectly. But when I read() my binary file, it got wrong data. I have already tried to use 'l' and 'b' when creating the binary file. But the parameter for opening binary file in my read() is in default (without specifying 'l' or 'b'). Commented Feb 25, 2015 at 10:06

1 Answer 1

0

The problem is probably (at least in part) an endian issue. On intel architecture (little endian), reading two bytes as uint8 followed by appending the binary representations is not going to give you the same result in general as reading two bytes as uint16.

The following script illustrates how swapping the order of the two uint8's will do the trick.

I changed some variable names and made things more concise for readability.

% declare an input int and the header (in binary string rep)

v = 68;
t2 = '01';

% write to file

x1 = dec2bin(v);
lenx = 16-length(x1);
x1hl = strcat(t2, '00000000000000');   % High and low
x1a = strcat(x1hl(1:lenx), num2str(x1));

% x1a = 0100000001000100

fp1=fopen('temp','w+');
fwrite(fp1, bin2dec(x1a), 'uint16');

% read the file

frewind(fp1);
vtest = fread(fp1, 1, 'uint16');       % upper 2 bits are reserved info.
dec2bin(vtest)

% ans = 100000001000100

% now read *two* bytes as two uint8

frewind(fp1);

byte1 = fread(fp1, 1, 'uint8');       % Raw X coordinates.
byte2 = fread(fp1, 1, 'uint8');       % upper 2 bits are reserved info.
tmpx = [dec2bin(byte2) dec2bin(byte1)]; % <-- swap the order

% tmpx = 10000001000100

Alternately just read the whole 2 bytes as uint16 and work from there.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.