0

The following code works perfectly to create 8 bit YUV files. I want to update it to be able to create 10 bit YUV files. But the char function does not allow integers more than 255.

I've tried changing it to short or int but I get incompatible pointer type errors. I've spent hours researching alternative approaches but have not been able to figure out how to adjust this code. Any help appreciated.

/*
MPEG 2 decoder bitstream xfer
*/

#include <stdio.h>
#include <stdlib.h>

#define TRUE        1
#define FALSE       0

int main(int argc, char **argv)
{
    FILE    *fpout;
    unsigned int    i, j;
    unsigned char   y, cb, cr, temp;

    if (argc != 5) {
        fprintf(stderr, "usage: pat<outfile> <Y> <Cb> <Cr>\n");
        exit(-1);
    }

    /*--- open binary file (for parsing) ---*/
    fpout = fopen(argv[1], "wb");
    if (fpout == 0) {
        fprintf(stderr, "Cannot open output file <%s>\n", argv[1]);
        exit(-1);
    }

    for(j = 0; j < 360; j++)  {
        for(i = 0; i < 960; i++)  {
            y = 16;
            cr = 128;
            cb = 128;
            fwrite(&cb, 1, 1, fpout);
            fwrite(&y, 1, 1, fpout);
            fwrite(&cr, 1, 1, fpout);
            fwrite(&y, 1, 1, fpout);
        }
    }
    for(j = 0; j < 360; j++)  {
        for(i = 0; i < 960; i++)  {
            if(i < 320 || i > 639)  {
                y = 16;
                cr = 128;
                cb = 128;
                fwrite(&cb, 1, 1, fpout);
                fwrite(&y, 1, 1, fpout);
                fwrite(&cr, 1, 1, fpout);
                fwrite(&y, 1, 1, fpout);
            }
            else  {
                temp = atoi(argv[2]);
                y = temp;
                temp = atoi(argv[3]);
                cb = temp;
                temp = atoi(argv[4]);
                cr = temp;
                fwrite(&cb, 1, 1, fpout);
                fwrite(&y, 1, 1, fpout);
                fwrite(&cr, 1, 1, fpout);
                fwrite(&y, 1, 1, fpout);
            }
        }
    }


    fclose(fpout);
    return 0;
stonehenge
  • 23
  • 1
  • 6
  • 3
    If `CHAR_BIT == 8` on your compiler, you cannot have a `char` variable with more than 8 bits. You will need to use a larger type in this case. – Govind Parmar Feb 20 '19 at 15:48
  • 1
    When using 8bit in YUV one byte is exactly one color. How is a YUV file stored with 10 bits? – KamilCuk Feb 20 '19 at 15:49
  • `temp = atoi(argv[2]);` if that arg will represent any value greater than `255`, then `char` simply won't be enough to store it. Unless of course you're on a very exotic system where `char` is greater than 8 bits. – Blaze Feb 20 '19 at 15:50
  • 2
    `short` is a good way, but transferring to the file you will encounter the problem of endianess, which is not a problem with 8bits. So after you have done your calculations, you should split every `short` into two bytes (simple mask and shift), according to the format of your destination files [often 16bit, which only 10 really used) – Giacomo Catenazzi Feb 20 '19 at 15:51
  • 1
    [Why shouldn't I use atoi()?](https://stackoverflow.com/q/17710018/995714). And did you read how the 10-bit YUV file is stored? Normally odd-sized image formats are packed somehow, like 5 bytes for four 10-bit channels withe the 4 LSBs in the last byte, because storing 10 bits of data in a 16-bit short is a huge waste of memory – phuclv Feb 20 '19 at 16:03
  • the posted code is missing the trailing closing brace '}'. – user3629249 Feb 20 '19 at 16:09
  • 1
    rather than: `#define TRUE 1 #define FALSE 0` it is much better to include the header file: `stdbool.h` – user3629249 Feb 20 '19 at 16:14
  • OT: regarding this kind of statement: `fwrite(&cb, 1, 1, fpout);` The code should always check the returned value (which should be the same as the third parameter to assure the operation was successful – user3629249 Feb 20 '19 at 16:16
  • here is what I found on how 10 bit YUV is stored. I need to go through it a bit more. https://learn.microsoft.com/en-us/windows/desktop/medfound/10-bit-and-16-bit-yuv-video-formats – stonehenge Feb 20 '19 at 16:36
  • The original code uses the packed format 4:2:2 UYVY and I believe it would be the same for the 10 bit file. – stonehenge Feb 20 '19 at 16:55
  • 1
    Ugh - Grab a C# library and do it there :) – Michael Dorgan Feb 20 '19 at 19:20
  • Which code is giving error on incompatible pointer type is not posted. If it is fwrite(), cast short or int pointer (&) first argument passed to fwrite() to char *. – anand Feb 21 '19 at 05:17

0 Answers0