static int decode_header(EXRContext *s)

{

    int magic_number, version, i, flags, sar = 0;

    int layer_match = 0;



    s->current_channel_offset = 0;

    s->xmin               = ~0;

    s->xmax               = ~0;

    s->ymin               = ~0;

    s->ymax               = ~0;

    s->xdelta             = ~0;

    s->ydelta             = ~0;

    s->channel_offsets[0] = -1;

    s->channel_offsets[1] = -1;

    s->channel_offsets[2] = -1;

    s->channel_offsets[3] = -1;

    s->pixel_type         = EXR_UNKNOWN;

    s->compression        = EXR_UNKN;

    s->nb_channels        = 0;

    s->w                  = 0;

    s->h                  = 0;

    s->tile_attr.xSize    = -1;

    s->tile_attr.ySize    = -1;

    s->is_tile            = 0;

    s->is_luma            = 0;



    if (bytestream2_get_bytes_left(&s->gb) < 10) {

        av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n");

        return AVERROR_INVALIDDATA;

    }



    magic_number = bytestream2_get_le32(&s->gb);

    if (magic_number != 20000630) {

        /* As per documentation of OpenEXR, it is supposed to be

         * int 20000630 little-endian */

        av_log(s->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", magic_number);

        return AVERROR_INVALIDDATA;

    }



    version = bytestream2_get_byte(&s->gb);

    if (version != 2) {

        avpriv_report_missing_feature(s->avctx, "Version %d", version);

        return AVERROR_PATCHWELCOME;

    }



    flags = bytestream2_get_le24(&s->gb);



    if (flags == 0x00)

        s->is_tile = 0;

    else if (flags & 0x02)

        s->is_tile = 1;

    else{

        avpriv_report_missing_feature(s->avctx, "flags %d", flags);

        return AVERROR_PATCHWELCOME;

    }



    // Parse the header

    while (bytestream2_get_bytes_left(&s->gb) > 0 && *s->gb.buffer) {

        int var_size;

        if ((var_size = check_header_variable(s, "channels",

                                              "chlist", 38)) >= 0) {

            GetByteContext ch_gb;

            if (!var_size)

                return AVERROR_INVALIDDATA;



            bytestream2_init(&ch_gb, s->gb.buffer, var_size);



            while (bytestream2_get_bytes_left(&ch_gb) >= 19) {

                EXRChannel *channel;

                enum ExrPixelType current_pixel_type;

                int channel_index = -1;

                int xsub, ysub;



                if (strcmp(s->layer, "") != 0) {

                    if (strncmp(ch_gb.buffer, s->layer, strlen(s->layer)) == 0) {

                        layer_match = 1;

                        av_log(s->avctx, AV_LOG_INFO,

                               "Channel match layer : %s.\n", ch_gb.buffer);

                        ch_gb.buffer += strlen(s->layer);

                        if (*ch_gb.buffer == '.')

                            ch_gb.buffer++;         /* skip dot if not given */

                    } else {

                        av_log(s->avctx, AV_LOG_INFO,

                               "Channel doesn't match layer : %s.\n", ch_gb.buffer);

                    }

                } else {

                    layer_match = 1;

                }



                if (layer_match) { /* only search channel if the layer match is valid */

                    if (!strcmp(ch_gb.buffer, "R") ||

                        !strcmp(ch_gb.buffer, "X") ||

                        !strcmp(ch_gb.buffer, "U")) {

                        channel_index = 0;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "G") ||

                               !strcmp(ch_gb.buffer, "V")) {

                        channel_index = 1;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "Y")) {

                        channel_index = 1;

                        s->is_luma = 1;

                    } else if (!strcmp(ch_gb.buffer, "B") ||

                               !strcmp(ch_gb.buffer, "Z") ||

                               !strcmp(ch_gb.buffer, "W")){

                               channel_index = 2;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "A")) {

                        channel_index = 3;

                    } else {

                        av_log(s->avctx, AV_LOG_WARNING,

                               "Unsupported channel %.256s.\n", ch_gb.buffer);

                    }

                }



                /* skip until you get a 0 */

                while (bytestream2_get_bytes_left(&ch_gb) > 0 &&

                       bytestream2_get_byte(&ch_gb))

                    continue;



                if (bytestream2_get_bytes_left(&ch_gb) < 4) {

                    av_log(s->avctx, AV_LOG_ERROR, "Incomplete header.\n");

                    return AVERROR_INVALIDDATA;

                }



                current_pixel_type = bytestream2_get_le32(&ch_gb);

                if (current_pixel_type >= EXR_UNKNOWN) {

                    avpriv_report_missing_feature(s->avctx, "Pixel type %d",

                                                  current_pixel_type);

                    return AVERROR_PATCHWELCOME;

                }



                bytestream2_skip(&ch_gb, 4);

                xsub = bytestream2_get_le32(&ch_gb);

                ysub = bytestream2_get_le32(&ch_gb);



                if (xsub != 1 || ysub != 1) {

                    avpriv_report_missing_feature(s->avctx,

                                                  "Subsampling %dx%d",

                                                  xsub, ysub);

                    return AVERROR_PATCHWELCOME;

                }



                if (s->channel_offsets[channel_index] == -1){/* channel have not been previously assign */

                    if (channel_index >= 0) {

                        if (s->pixel_type != EXR_UNKNOWN &&

                            s->pixel_type != current_pixel_type) {

                            av_log(s->avctx, AV_LOG_ERROR,

                                   "RGB channels not of the same depth.\n");

                            return AVERROR_INVALIDDATA;

                        }

                        s->pixel_type                     = current_pixel_type;

                        s->channel_offsets[channel_index] = s->current_channel_offset;

                    }

                }



                s->channels = av_realloc(s->channels,

                                         ++s->nb_channels * sizeof(EXRChannel));

                if (!s->channels)

                    return AVERROR(ENOMEM);

                channel             = &s->channels[s->nb_channels - 1];

                channel->pixel_type = current_pixel_type;

                channel->xsub       = xsub;

                channel->ysub       = ysub;



                s->current_channel_offset += 1 << current_pixel_type;

            }



            /* Check if all channels are set with an offset or if the channels

             * are causing an overflow  */

            if (!s->is_luma){/* if we expected to have at least 3 channels */

                if (FFMIN3(s->channel_offsets[0],

                           s->channel_offsets[1],

                           s->channel_offsets[2]) < 0) {

                    if (s->channel_offsets[0] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing red channel.\n");

                    if (s->channel_offsets[1] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing green channel.\n");

                    if (s->channel_offsets[2] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing blue channel.\n");

                    return AVERROR_INVALIDDATA;

                }

            }



            // skip one last byte and update main gb

            s->gb.buffer = ch_gb.buffer + 1;

            continue;

        } else if ((var_size = check_header_variable(s, "dataWindow", "box2i",

                                                     31)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            s->xmin   = bytestream2_get_le32(&s->gb);

            s->ymin   = bytestream2_get_le32(&s->gb);

            s->xmax   = bytestream2_get_le32(&s->gb);

            s->ymax   = bytestream2_get_le32(&s->gb);

            s->xdelta = (s->xmax - s->xmin) + 1;

            s->ydelta = (s->ymax - s->ymin) + 1;



            continue;

        } else if ((var_size = check_header_variable(s, "displayWindow",

                                                     "box2i", 34)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            bytestream2_skip(&s->gb, 8);

            s->w = bytestream2_get_le32(&s->gb) + 1;

            s->h = bytestream2_get_le32(&s->gb) + 1;



            continue;

        } else if ((var_size = check_header_variable(s, "lineOrder",

                                                     "lineOrder", 25)) >= 0) {

            int line_order;

            if (!var_size)

                return AVERROR_INVALIDDATA;



            line_order = bytestream2_get_byte(&s->gb);

            av_log(s->avctx, AV_LOG_DEBUG, "line order: %d.\n", line_order);

            if (line_order > 2) {

                av_log(s->avctx, AV_LOG_ERROR, "Unknown line order.\n");

                return AVERROR_INVALIDDATA;

            }



            continue;

        } else if ((var_size = check_header_variable(s, "pixelAspectRatio",

                                                     "float", 31)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            sar = bytestream2_get_le32(&s->gb);



            continue;

        } else if ((var_size = check_header_variable(s, "compression",

                                                     "compression", 29)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            if (s->compression == EXR_UNKN)

                s->compression = bytestream2_get_byte(&s->gb);

            else

                av_log(s->avctx, AV_LOG_WARNING,

                       "Found more than one compression attribute.\n");



            continue;

        } else if ((var_size = check_header_variable(s, "tiles",

                                                     "tiledesc", 22)) >= 0) {

            char tileLevel;



            if (!s->is_tile)

                av_log(s->avctx, AV_LOG_WARNING,

                       "Found tile attribute and scanline flags. Exr will be interpreted as scanline.\n");



            s->tile_attr.xSize = bytestream2_get_le32(&s->gb);

            s->tile_attr.ySize = bytestream2_get_le32(&s->gb);



            tileLevel = bytestream2_get_byte(&s->gb);

            s->tile_attr.level_mode = tileLevel & 0x0f;

            s->tile_attr.level_round = (tileLevel >> 4) & 0x0f;



            if (s->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN){

                avpriv_report_missing_feature(s->avctx, "Tile level mode %d",

                                              s->tile_attr.level_mode);

                return AVERROR_PATCHWELCOME;

            }



            if (s->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) {

                avpriv_report_missing_feature(s->avctx, "Tile level round %d",

                                              s->tile_attr.level_round);

                return AVERROR_PATCHWELCOME;

            }



            continue;

        }



        // Check if there are enough bytes for a header

        if (bytestream2_get_bytes_left(&s->gb) <= 9) {

            av_log(s->avctx, AV_LOG_ERROR, "Incomplete header\n");

            return AVERROR_INVALIDDATA;

        }



        // Process unknown variables

        for (i = 0; i < 2; i++) // value_name and value_type

            while (bytestream2_get_byte(&s->gb) != 0);



        // Skip variable length

        bytestream2_skip(&s->gb, bytestream2_get_le32(&s->gb));

    }



    ff_set_sar(s->avctx, av_d2q(av_int2float(sar), 255));



    if (s->compression == EXR_UNKN) {

        av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n");

        return AVERROR_INVALIDDATA;

    }



    if (s->is_tile) {

        if (s->tile_attr.xSize < 1 || s->tile_attr.ySize < 1) {

            av_log(s->avctx, AV_LOG_ERROR, "Invalid tile attribute.\n");

            return AVERROR_INVALIDDATA;

        }

    }



    if (bytestream2_get_bytes_left(&s->gb) <= 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n");

        return AVERROR_INVALIDDATA;

    }



    // aaand we are done

    bytestream2_skip(&s->gb, 1);

    return 0;

}

static int decode_header(EXRContext *s)

{

    int magic_number, version, i, flags, sar = 0;

    int layer_match = 0;



    s->current_channel_offset = 0;

    s->xmin               = ~0;

    s->xmax               = ~0;

    s->ymin               = ~0;

    s->ymax               = ~0;

    s->xdelta             = ~0;

    s->ydelta             = ~0;

    s->channel_offsets[0] = -1;

    s->channel_offsets[1] = -1;

    s->channel_offsets[2] = -1;

    s->channel_offsets[3] = -1;

    s->pixel_type         = EXR_UNKNOWN;

    s->compression        = EXR_UNKN;

    s->nb_channels        = 0;

    s->w                  = 0;

    s->h                  = 0;

    s->tile_attr.xSize    = -1;

    s->tile_attr.ySize    = -1;

    s->is_tile            = 0;

    s->is_luma            = 0;



    if (bytestream2_get_bytes_left(&s->gb) < 10) {

        av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n");

        return AVERROR_INVALIDDATA;

    }



    magic_number = bytestream2_get_le32(&s->gb);

    if (magic_number != 20000630) {

        



        av_log(s->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", magic_number);

        return AVERROR_INVALIDDATA;

    }



    version = bytestream2_get_byte(&s->gb);

    if (version != 2) {

        avpriv_report_missing_feature(s->avctx, "Version %d", version);

        return AVERROR_PATCHWELCOME;

    }



    flags = bytestream2_get_le24(&s->gb);



    if (flags == 0x00)

        s->is_tile = 0;

    else if (flags & 0x02)

        s->is_tile = 1;

    else{

        avpriv_report_missing_feature(s->avctx, "flags %d", flags);

        return AVERROR_PATCHWELCOME;

    }



    

    while (bytestream2_get_bytes_left(&s->gb) > 0 && *s->gb.buffer) {

        int var_size;

        if ((var_size = check_header_variable(s, "channels",

                                              "chlist", 38)) >= 0) {

            GetByteContext ch_gb;

            if (!var_size)

                return AVERROR_INVALIDDATA;



            bytestream2_init(&ch_gb, s->gb.buffer, var_size);



            while (bytestream2_get_bytes_left(&ch_gb) >= 19) {

                EXRChannel *channel;

                enum ExrPixelType current_pixel_type;

                int channel_index = -1;

                int xsub, ysub;



                if (strcmp(s->layer, "") != 0) {

                    if (strncmp(ch_gb.buffer, s->layer, strlen(s->layer)) == 0) {

                        layer_match = 1;

                        av_log(s->avctx, AV_LOG_INFO,

                               "Channel match layer : %s.\n", ch_gb.buffer);

                        ch_gb.buffer += strlen(s->layer);

                        if (*ch_gb.buffer == '.')

                            ch_gb.buffer++;         

                    } else {

                        av_log(s->avctx, AV_LOG_INFO,

                               "Channel doesn't match layer : %s.\n", ch_gb.buffer);

                    }

                } else {

                    layer_match = 1;

                }



                if (layer_match) { 

                    if (!strcmp(ch_gb.buffer, "R") ||

                        !strcmp(ch_gb.buffer, "X") ||

                        !strcmp(ch_gb.buffer, "U")) {

                        channel_index = 0;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "G") ||

                               !strcmp(ch_gb.buffer, "V")) {

                        channel_index = 1;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "Y")) {

                        channel_index = 1;

                        s->is_luma = 1;

                    } else if (!strcmp(ch_gb.buffer, "B") ||

                               !strcmp(ch_gb.buffer, "Z") ||

                               !strcmp(ch_gb.buffer, "W")){

                               channel_index = 2;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "A")) {

                        channel_index = 3;

                    } else {

                        av_log(s->avctx, AV_LOG_WARNING,

                               "Unsupported channel %.256s.\n", ch_gb.buffer);

                    }

                }



                

                while (bytestream2_get_bytes_left(&ch_gb) > 0 &&

                       bytestream2_get_byte(&ch_gb))

                    continue;



                if (bytestream2_get_bytes_left(&ch_gb) < 4) {

                    av_log(s->avctx, AV_LOG_ERROR, "Incomplete header.\n");

                    return AVERROR_INVALIDDATA;

                }



                current_pixel_type = bytestream2_get_le32(&ch_gb);

                if (current_pixel_type >= EXR_UNKNOWN) {

                    avpriv_report_missing_feature(s->avctx, "Pixel type %d",

                                                  current_pixel_type);

                    return AVERROR_PATCHWELCOME;

                }



                bytestream2_skip(&ch_gb, 4);

                xsub = bytestream2_get_le32(&ch_gb);

                ysub = bytestream2_get_le32(&ch_gb);



                if (xsub != 1 || ysub != 1) {

                    avpriv_report_missing_feature(s->avctx,

                                                  "Subsampling %dx%d",

                                                  xsub, ysub);

                    return AVERROR_PATCHWELCOME;

                }



                if (s->channel_offsets[channel_index] == -1){

                    if (channel_index >= 0) {

                        if (s->pixel_type != EXR_UNKNOWN &&

                            s->pixel_type != current_pixel_type) {

                            av_log(s->avctx, AV_LOG_ERROR,

                                   "RGB channels not of the same depth.\n");

                            return AVERROR_INVALIDDATA;

                        }

                        s->pixel_type                     = current_pixel_type;

                        s->channel_offsets[channel_index] = s->current_channel_offset;

                    }

                }



                s->channels = av_realloc(s->channels,

                                         ++s->nb_channels * sizeof(EXRChannel));

                if (!s->channels)

                    return AVERROR(ENOMEM);

                channel             = &s->channels[s->nb_channels - 1];

                channel->pixel_type = current_pixel_type;

                channel->xsub       = xsub;

                channel->ysub       = ysub;



                s->current_channel_offset += 1 << current_pixel_type;

            }



            



            if (!s->is_luma){

                if (FFMIN3(s->channel_offsets[0],

                           s->channel_offsets[1],

                           s->channel_offsets[2]) < 0) {

                    if (s->channel_offsets[0] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing red channel.\n");

                    if (s->channel_offsets[1] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing green channel.\n");

                    if (s->channel_offsets[2] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing blue channel.\n");

                    return AVERROR_INVALIDDATA;

                }

            }



            

            s->gb.buffer = ch_gb.buffer + 1;

            continue;

        } else if ((var_size = check_header_variable(s, "dataWindow", "box2i",

                                                     31)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            s->xmin   = bytestream2_get_le32(&s->gb);

            s->ymin   = bytestream2_get_le32(&s->gb);

            s->xmax   = bytestream2_get_le32(&s->gb);

            s->ymax   = bytestream2_get_le32(&s->gb);

            s->xdelta = (s->xmax - s->xmin) + 1;

            s->ydelta = (s->ymax - s->ymin) + 1;



            continue;

        } else if ((var_size = check_header_variable(s, "displayWindow",

                                                     "box2i", 34)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            bytestream2_skip(&s->gb, 8);

            s->w = bytestream2_get_le32(&s->gb) + 1;

            s->h = bytestream2_get_le32(&s->gb) + 1;



            continue;

        } else if ((var_size = check_header_variable(s, "lineOrder",

                                                     "lineOrder", 25)) >= 0) {

            int line_order;

            if (!var_size)

                return AVERROR_INVALIDDATA;



            line_order = bytestream2_get_byte(&s->gb);

            av_log(s->avctx, AV_LOG_DEBUG, "line order: %d.\n", line_order);

            if (line_order > 2) {

                av_log(s->avctx, AV_LOG_ERROR, "Unknown line order.\n");

                return AVERROR_INVALIDDATA;

            }



            continue;

        } else if ((var_size = check_header_variable(s, "pixelAspectRatio",

                                                     "float", 31)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            sar = bytestream2_get_le32(&s->gb);



            continue;

        } else if ((var_size = check_header_variable(s, "compression",

                                                     "compression", 29)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;



            if (s->compression == EXR_UNKN)

                s->compression = bytestream2_get_byte(&s->gb);

            else

                av_log(s->avctx, AV_LOG_WARNING,

                       "Found more than one compression attribute.\n");



            continue;

        } else if ((var_size = check_header_variable(s, "tiles",

                                                     "tiledesc", 22)) >= 0) {

            char tileLevel;



            if (!s->is_tile)

                av_log(s->avctx, AV_LOG_WARNING,

                       "Found tile attribute and scanline flags. Exr will be interpreted as scanline.\n");



            s->tile_attr.xSize = bytestream2_get_le32(&s->gb);

            s->tile_attr.ySize = bytestream2_get_le32(&s->gb);



            tileLevel = bytestream2_get_byte(&s->gb);

            s->tile_attr.level_mode = tileLevel & 0x0f;

            s->tile_attr.level_round = (tileLevel >> 4) & 0x0f;



            if (s->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN){

                avpriv_report_missing_feature(s->avctx, "Tile level mode %d",

                                              s->tile_attr.level_mode);

                return AVERROR_PATCHWELCOME;

            }



            if (s->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) {

                avpriv_report_missing_feature(s->avctx, "Tile level round %d",

                                              s->tile_attr.level_round);

                return AVERROR_PATCHWELCOME;

            }



            continue;

        }



        

        if (bytestream2_get_bytes_left(&s->gb) <= 9) {

            av_log(s->avctx, AV_LOG_ERROR, "Incomplete header\n");

            return AVERROR_INVALIDDATA;

        }



        

        for (i = 0; i < 2; i++) 

            while (bytestream2_get_byte(&s->gb) != 0);



        

        bytestream2_skip(&s->gb, bytestream2_get_le32(&s->gb));

    }



    ff_set_sar(s->avctx, av_d2q(av_int2float(sar), 255));



    if (s->compression == EXR_UNKN) {

        av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n");

        return AVERROR_INVALIDDATA;

    }



    if (s->is_tile) {

        if (s->tile_attr.xSize < 1 || s->tile_attr.ySize < 1) {

            av_log(s->avctx, AV_LOG_ERROR, "Invalid tile attribute.\n");

            return AVERROR_INVALIDDATA;

        }

    }



    if (bytestream2_get_bytes_left(&s->gb) <= 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n");

        return AVERROR_INVALIDDATA;

    }



    

    bytestream2_skip(&s->gb, 1);

    return 0;

}

                    if (channel_index >= 0) {
static int FUNC_0(EXRContext *VAR_0)

{

    int VAR_1, VAR_2, VAR_3, VAR_4, VAR_5 = 0;

    int VAR_6 = 0;



    VAR_0->current_channel_offset = 0;

    VAR_0->xmin               = ~0;

    VAR_0->xmax               = ~0;

    VAR_0->ymin               = ~0;

    VAR_0->ymax               = ~0;

    VAR_0->xdelta             = ~0;

    VAR_0->ydelta             = ~0;

    VAR_0->channel_offsets[0] = -1;

    VAR_0->channel_offsets[1] = -1;

    VAR_0->channel_offsets[2] = -1;

    VAR_0->channel_offsets[3] = -1;

    VAR_0->pixel_type         = EXR_UNKNOWN;

    VAR_0->compression        = EXR_UNKN;

    VAR_0->nb_channels        = 0;

    VAR_0->w                  = 0;

    VAR_0->h                  = 0;

    VAR_0->tile_attr.xSize    = -1;

    VAR_0->tile_attr.ySize    = -1;

    VAR_0->is_tile            = 0;

    VAR_0->is_luma            = 0;



    if (bytestream2_get_bytes_left(&VAR_0->gb) < 10) {

        av_log(VAR_0->avctx, AV_LOG_ERROR, "Header too short to parse.\n");

        return AVERROR_INVALIDDATA;

    }



    VAR_1 = bytestream2_get_le32(&VAR_0->gb);

    if (VAR_1 != 20000630) {

        



        av_log(VAR_0->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", VAR_1);

        return AVERROR_INVALIDDATA;

    }



    VAR_2 = bytestream2_get_byte(&VAR_0->gb);

    if (VAR_2 != 2) {

        avpriv_report_missing_feature(VAR_0->avctx, "Version %d", VAR_2);

        return AVERROR_PATCHWELCOME;

    }



    VAR_4 = bytestream2_get_le24(&VAR_0->gb);



    if (VAR_4 == 0x00)

        VAR_0->is_tile = 0;

    else if (VAR_4 & 0x02)

        VAR_0->is_tile = 1;

    else{

        avpriv_report_missing_feature(VAR_0->avctx, "VAR_4 %d", VAR_4);

        return AVERROR_PATCHWELCOME;

    }



    

    while (bytestream2_get_bytes_left(&VAR_0->gb) > 0 && *VAR_0->gb.buffer) {

        int VAR_7;

        if ((VAR_7 = check_header_variable(VAR_0, "channels",

                                              "chlist", 38)) >= 0) {

            GetByteContext ch_gb;

            if (!VAR_7)

                return AVERROR_INVALIDDATA;



            bytestream2_init(&ch_gb, VAR_0->gb.buffer, VAR_7);



            while (bytestream2_get_bytes_left(&ch_gb) >= 19) {

                EXRChannel *channel;

                enum ExrPixelType VAR_8;

                int VAR_9 = -1;

                int VAR_10, VAR_11;



                if (strcmp(VAR_0->layer, "") != 0) {

                    if (strncmp(ch_gb.buffer, VAR_0->layer, strlen(VAR_0->layer)) == 0) {

                        VAR_6 = 1;

                        av_log(VAR_0->avctx, AV_LOG_INFO,

                               "Channel match layer : %VAR_0.\n", ch_gb.buffer);

                        ch_gb.buffer += strlen(VAR_0->layer);

                        if (*ch_gb.buffer == '.')

                            ch_gb.buffer++;         

                    } else {

                        av_log(VAR_0->avctx, AV_LOG_INFO,

                               "Channel doesn't match layer : %VAR_0.\n", ch_gb.buffer);

                    }

                } else {

                    VAR_6 = 1;

                }



                if (VAR_6) { 

                    if (!strcmp(ch_gb.buffer, "R") ||

                        !strcmp(ch_gb.buffer, "X") ||

                        !strcmp(ch_gb.buffer, "U")) {

                        VAR_9 = 0;

                        VAR_0->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "G") ||

                               !strcmp(ch_gb.buffer, "V")) {

                        VAR_9 = 1;

                        VAR_0->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "Y")) {

                        VAR_9 = 1;

                        VAR_0->is_luma = 1;

                    } else if (!strcmp(ch_gb.buffer, "B") ||

                               !strcmp(ch_gb.buffer, "Z") ||

                               !strcmp(ch_gb.buffer, "W")){

                               VAR_9 = 2;

                        VAR_0->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "A")) {

                        VAR_9 = 3;

                    } else {

                        av_log(VAR_0->avctx, AV_LOG_WARNING,

                               "Unsupported channel %.256s.\n", ch_gb.buffer);

                    }

                }



                

                while (bytestream2_get_bytes_left(&ch_gb) > 0 &&

                       bytestream2_get_byte(&ch_gb))

                    continue;



                if (bytestream2_get_bytes_left(&ch_gb) < 4) {

                    av_log(VAR_0->avctx, AV_LOG_ERROR, "Incomplete header.\n");

                    return AVERROR_INVALIDDATA;

                }



                VAR_8 = bytestream2_get_le32(&ch_gb);

                if (VAR_8 >= EXR_UNKNOWN) {

                    avpriv_report_missing_feature(VAR_0->avctx, "Pixel type %d",

                                                  VAR_8);

                    return AVERROR_PATCHWELCOME;

                }



                bytestream2_skip(&ch_gb, 4);

                VAR_10 = bytestream2_get_le32(&ch_gb);

                VAR_11 = bytestream2_get_le32(&ch_gb);



                if (VAR_10 != 1 || VAR_11 != 1) {

                    avpriv_report_missing_feature(VAR_0->avctx,

                                                  "Subsampling %dx%d",

                                                  VAR_10, VAR_11);

                    return AVERROR_PATCHWELCOME;

                }



                if (VAR_0->channel_offsets[VAR_9] == -1){

                    if (VAR_9 >= 0) {

                        if (VAR_0->pixel_type != EXR_UNKNOWN &&

                            VAR_0->pixel_type != VAR_8) {

                            av_log(VAR_0->avctx, AV_LOG_ERROR,

                                   "RGB channels not of the same depth.\n");

                            return AVERROR_INVALIDDATA;

                        }

                        VAR_0->pixel_type                     = VAR_8;

                        VAR_0->channel_offsets[VAR_9] = VAR_0->current_channel_offset;

                    }

                }



                VAR_0->channels = av_realloc(VAR_0->channels,

                                         ++VAR_0->nb_channels * sizeof(EXRChannel));

                if (!VAR_0->channels)

                    return AVERROR(ENOMEM);

                channel             = &VAR_0->channels[VAR_0->nb_channels - 1];

                channel->pixel_type = VAR_8;

                channel->VAR_10       = VAR_10;

                channel->VAR_11       = VAR_11;



                VAR_0->current_channel_offset += 1 << VAR_8;

            }



            



            if (!VAR_0->is_luma){

                if (FFMIN3(VAR_0->channel_offsets[0],

                           VAR_0->channel_offsets[1],

                           VAR_0->channel_offsets[2]) < 0) {

                    if (VAR_0->channel_offsets[0] < 0)

                        av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing red channel.\n");

                    if (VAR_0->channel_offsets[1] < 0)

                        av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing green channel.\n");

                    if (VAR_0->channel_offsets[2] < 0)

                        av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing blue channel.\n");

                    return AVERROR_INVALIDDATA;

                }

            }



            

            VAR_0->gb.buffer = ch_gb.buffer + 1;

            continue;

        } else if ((VAR_7 = check_header_variable(VAR_0, "dataWindow", "box2i",

                                                     31)) >= 0) {

            if (!VAR_7)

                return AVERROR_INVALIDDATA;



            VAR_0->xmin   = bytestream2_get_le32(&VAR_0->gb);

            VAR_0->ymin   = bytestream2_get_le32(&VAR_0->gb);

            VAR_0->xmax   = bytestream2_get_le32(&VAR_0->gb);

            VAR_0->ymax   = bytestream2_get_le32(&VAR_0->gb);

            VAR_0->xdelta = (VAR_0->xmax - VAR_0->xmin) + 1;

            VAR_0->ydelta = (VAR_0->ymax - VAR_0->ymin) + 1;



            continue;

        } else if ((VAR_7 = check_header_variable(VAR_0, "displayWindow",

                                                     "box2i", 34)) >= 0) {

            if (!VAR_7)

                return AVERROR_INVALIDDATA;



            bytestream2_skip(&VAR_0->gb, 8);

            VAR_0->w = bytestream2_get_le32(&VAR_0->gb) + 1;

            VAR_0->h = bytestream2_get_le32(&VAR_0->gb) + 1;



            continue;

        } else if ((VAR_7 = check_header_variable(VAR_0, "lineOrder",

                                                     "lineOrder", 25)) >= 0) {

            int VAR_12;

            if (!VAR_7)

                return AVERROR_INVALIDDATA;



            VAR_12 = bytestream2_get_byte(&VAR_0->gb);

            av_log(VAR_0->avctx, AV_LOG_DEBUG, "line order: %d.\n", VAR_12);

            if (VAR_12 > 2) {

                av_log(VAR_0->avctx, AV_LOG_ERROR, "Unknown line order.\n");

                return AVERROR_INVALIDDATA;

            }



            continue;

        } else if ((VAR_7 = check_header_variable(VAR_0, "pixelAspectRatio",

                                                     "float", 31)) >= 0) {

            if (!VAR_7)

                return AVERROR_INVALIDDATA;



            VAR_5 = bytestream2_get_le32(&VAR_0->gb);



            continue;

        } else if ((VAR_7 = check_header_variable(VAR_0, "compression",

                                                     "compression", 29)) >= 0) {

            if (!VAR_7)

                return AVERROR_INVALIDDATA;



            if (VAR_0->compression == EXR_UNKN)

                VAR_0->compression = bytestream2_get_byte(&VAR_0->gb);

            else

                av_log(VAR_0->avctx, AV_LOG_WARNING,

                       "Found more than one compression attribute.\n");



            continue;

        } else if ((VAR_7 = check_header_variable(VAR_0, "tiles",

                                                     "tiledesc", 22)) >= 0) {

            char VAR_13;



            if (!VAR_0->is_tile)

                av_log(VAR_0->avctx, AV_LOG_WARNING,

                       "Found tile attribute and scanline VAR_4. Exr will be interpreted as scanline.\n");



            VAR_0->tile_attr.xSize = bytestream2_get_le32(&VAR_0->gb);

            VAR_0->tile_attr.ySize = bytestream2_get_le32(&VAR_0->gb);



            VAR_13 = bytestream2_get_byte(&VAR_0->gb);

            VAR_0->tile_attr.level_mode = VAR_13 & 0x0f;

            VAR_0->tile_attr.level_round = (VAR_13 >> 4) & 0x0f;



            if (VAR_0->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN){

                avpriv_report_missing_feature(VAR_0->avctx, "Tile level mode %d",

                                              VAR_0->tile_attr.level_mode);

                return AVERROR_PATCHWELCOME;

            }



            if (VAR_0->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) {

                avpriv_report_missing_feature(VAR_0->avctx, "Tile level round %d",

                                              VAR_0->tile_attr.level_round);

                return AVERROR_PATCHWELCOME;

            }



            continue;

        }



        

        if (bytestream2_get_bytes_left(&VAR_0->gb) <= 9) {

            av_log(VAR_0->avctx, AV_LOG_ERROR, "Incomplete header\n");

            return AVERROR_INVALIDDATA;

        }



        

        for (VAR_3 = 0; VAR_3 < 2; VAR_3++) 

            while (bytestream2_get_byte(&VAR_0->gb) != 0);



        

        bytestream2_skip(&VAR_0->gb, bytestream2_get_le32(&VAR_0->gb));

    }



    ff_set_sar(VAR_0->avctx, av_d2q(av_int2float(VAR_5), 255));



    if (VAR_0->compression == EXR_UNKN) {

        av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing compression attribute.\n");

        return AVERROR_INVALIDDATA;

    }



    if (VAR_0->is_tile) {

        if (VAR_0->tile_attr.xSize < 1 || VAR_0->tile_attr.ySize < 1) {

            av_log(VAR_0->avctx, AV_LOG_ERROR, "Invalid tile attribute.\n");

            return AVERROR_INVALIDDATA;

        }

    }



    if (bytestream2_get_bytes_left(&VAR_0->gb) <= 0) {

        av_log(VAR_0->avctx, AV_LOG_ERROR, "Incomplete frame.\n");

        return AVERROR_INVALIDDATA;

    }



    

    bytestream2_skip(&VAR_0->gb, 1);

    return 0;

}

static int FUNC_0(EXRContext *VAR_0)
{ int VAR_1, VAR_2, VAR_3, VAR_4, VAR_5 = 0; int VAR_6 = 0; VAR_0->current_channel_offset = 0; VAR_0->xmin               = ~0; VAR_0->xmax               = ~0; VAR_0->ymin               = ~0; VAR_0->ymax               = ~0; VAR_0->xdelta             = ~0; VAR_0->ydelta             = ~0; VAR_0->channel_offsets[0] = -1; VAR_0->channel_offsets[1] = -1; VAR_0->channel_offsets[2] = -1; VAR_0->channel_offsets[3] = -1; VAR_0->pixel_type         = EXR_UNKNOWN; VAR_0->compression        = EXR_UNKN; VAR_0->nb_channels        = 0; VAR_0->w                  = 0; VAR_0->h                  = 0; VAR_0->tile_attr.xSize    = -1; VAR_0->tile_attr.ySize    = -1; VAR_0->is_tile            = 0; VAR_0->is_luma            = 0; if (bytestream2_get_bytes_left(&VAR_0->gb) < 10) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Header too short to parse.\n"); return AVERROR_INVALIDDATA; } VAR_1 = bytestream2_get_le32(&VAR_0->gb); if (VAR_1 != 20000630) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", VAR_1); return AVERROR_INVALIDDATA; } VAR_2 = bytestream2_get_byte(&VAR_0->gb); if (VAR_2 != 2) { avpriv_report_missing_feature(VAR_0->avctx, "Version %d", VAR_2); return AVERROR_PATCHWELCOME; } VAR_4 = bytestream2_get_le24(&VAR_0->gb); if (VAR_4 == 0x00)
VAR_0->is_tile = 0; else if (VAR_4 & 0x02)
VAR_0->is_tile = 1; else{ avpriv_report_missing_feature(VAR_0->avctx, "VAR_4 %d", VAR_4); return AVERROR_PATCHWELCOME; } while (bytestream2_get_bytes_left(&VAR_0->gb) > 0 && *VAR_0->gb.buffer) { int VAR_7; if ((VAR_7 = check_header_variable(VAR_0, "channels",
"chlist", 38)) >= 0) { GetByteContext ch_gb; if (!VAR_7)
return AVERROR_INVALIDDATA; bytestream2_init(&ch_gb, VAR_0->gb.buffer, VAR_7); while (bytestream2_get_bytes_left(&ch_gb) >= 19) { EXRChannel *channel; enum ExrPixelType VAR_8; int VAR_9 = -1; int VAR_10, VAR_11; if (strcmp(VAR_0->layer, "") != 0) { if (strncmp(ch_gb.buffer, VAR_0->layer, strlen(VAR_0->layer)) == 0) { VAR_6 = 1; av_log(VAR_0->avctx, AV_LOG_INFO,
"Channel match layer : %VAR_0.\n", ch_gb.buffer); ch_gb.buffer += strlen(VAR_0->layer); if (*ch_gb.buffer == '.')
ch_gb.buffer++; } else { av_log(VAR_0->avctx, AV_LOG_INFO,
"Channel doesn't match layer : %VAR_0.\n", ch_gb.buffer); } } else { VAR_6 = 1; } if (VAR_6) { if (!strcmp(ch_gb.buffer, "R") ||
!strcmp(ch_gb.buffer, "X") ||
!strcmp(ch_gb.buffer, "U")) { VAR_9 = 0; VAR_0->is_luma = 0; } else if (!strcmp(ch_gb.buffer, "G") || !strcmp(ch_gb.buffer, "V")) { VAR_9 = 1; VAR_0->is_luma = 0; } else if (!strcmp(ch_gb.buffer, "Y")) { VAR_9 = 1; VAR_0->is_luma = 1; } else if (!strcmp(ch_gb.buffer, "B") || !strcmp(ch_gb.buffer, "Z") ||
!strcmp(ch_gb.buffer, "W")){ VAR_9 = 2; VAR_0->is_luma = 0; } else if (!strcmp(ch_gb.buffer, "A")) { VAR_9 = 3; } else { av_log(VAR_0->avctx, AV_LOG_WARNING,
"Unsupported channel %.256s.\n", ch_gb.buffer); } } while (bytestream2_get_bytes_left(&ch_gb) > 0 &&
bytestream2_get_byte(&ch_gb))
continue; if (bytestream2_get_bytes_left(&ch_gb) < 4) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Incomplete header.\n"); return AVERROR_INVALIDDATA; } VAR_8 = bytestream2_get_le32(&ch_gb); if (VAR_8 >= EXR_UNKNOWN) { avpriv_report_missing_feature(VAR_0->avctx, "Pixel type %d",
VAR_8); return AVERROR_PATCHWELCOME; } bytestream2_skip(&ch_gb, 4); VAR_10 = bytestream2_get_le32(&ch_gb); VAR_11 = bytestream2_get_le32(&ch_gb); if (VAR_10 != 1 || VAR_11 != 1) { avpriv_report_missing_feature(VAR_0->avctx,
"Subsampling %dx%d",
VAR_10, VAR_11); return AVERROR_PATCHWELCOME; } if (VAR_0->channel_offsets[VAR_9] == -1){ if (VAR_9 >= 0) { if (VAR_0->pixel_type != EXR_UNKNOWN &&
VAR_0->pixel_type != VAR_8) { av_log(VAR_0->avctx, AV_LOG_ERROR,
"RGB channels not of the same depth.\n"); return AVERROR_INVALIDDATA; } VAR_0->pixel_type                     = VAR_8; VAR_0->channel_offsets[VAR_9] = VAR_0->current_channel_offset; } } VAR_0->channels = av_realloc(VAR_0->channels,
++VAR_0->nb_channels * sizeof(EXRChannel)); if (!VAR_0->channels)
return AVERROR(ENOMEM); channel             = &VAR_0->channels[VAR_0->nb_channels - 1]; channel->pixel_type = VAR_8; channel->VAR_10       = VAR_10; channel->VAR_11       = VAR_11; VAR_0->current_channel_offset += 1 << VAR_8; } if (!VAR_0->is_luma){ if (FFMIN3(VAR_0->channel_offsets[0],
VAR_0->channel_offsets[1],
VAR_0->channel_offsets[2]) < 0) { if (VAR_0->channel_offsets[0] < 0)
av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing red channel.\n"); if (VAR_0->channel_offsets[1] < 0)
av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing green channel.\n"); if (VAR_0->channel_offsets[2] < 0)
av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing blue channel.\n"); return AVERROR_INVALIDDATA; } } VAR_0->gb.buffer = ch_gb.buffer + 1; continue; } else if ((VAR_7 = check_header_variable(VAR_0, "dataWindow", "box2i", 31)) >= 0) { if (!VAR_7)
return AVERROR_INVALIDDATA; VAR_0->xmin   = bytestream2_get_le32(&VAR_0->gb); VAR_0->ymin   = bytestream2_get_le32(&VAR_0->gb); VAR_0->xmax   = bytestream2_get_le32(&VAR_0->gb); VAR_0->ymax   = bytestream2_get_le32(&VAR_0->gb); VAR_0->xdelta = (VAR_0->xmax - VAR_0->xmin) + 1; VAR_0->ydelta = (VAR_0->ymax - VAR_0->ymin) + 1; continue; } else if ((VAR_7 = check_header_variable(VAR_0, "displayWindow", "box2i", 34)) >= 0) { if (!VAR_7)
return AVERROR_INVALIDDATA; bytestream2_skip(&VAR_0->gb, 8); VAR_0->w = bytestream2_get_le32(&VAR_0->gb) + 1; VAR_0->h = bytestream2_get_le32(&VAR_0->gb) + 1; continue; } else if ((VAR_7 = check_header_variable(VAR_0, "lineOrder", "lineOrder", 25)) >= 0) { int VAR_12; if (!VAR_7)
return AVERROR_INVALIDDATA; VAR_12 = bytestream2_get_byte(&VAR_0->gb); av_log(VAR_0->avctx, AV_LOG_DEBUG, "line order: %d.\n", VAR_12); if (VAR_12 > 2) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Unknown line order.\n"); return AVERROR_INVALIDDATA; } continue; } else if ((VAR_7 = check_header_variable(VAR_0, "pixelAspectRatio", "float", 31)) >= 0) { if (!VAR_7)
return AVERROR_INVALIDDATA; VAR_5 = bytestream2_get_le32(&VAR_0->gb); continue; } else if ((VAR_7 = check_header_variable(VAR_0, "compression", "compression", 29)) >= 0) { if (!VAR_7)
return AVERROR_INVALIDDATA; if (VAR_0->compression == EXR_UNKN)
VAR_0->compression = bytestream2_get_byte(&VAR_0->gb); else
av_log(VAR_0->avctx, AV_LOG_WARNING,
"Found more than one compression attribute.\n"); continue; } else if ((VAR_7 = check_header_variable(VAR_0, "tiles", "tiledesc", 22)) >= 0) { char VAR_13; if (!VAR_0->is_tile)
av_log(VAR_0->avctx, AV_LOG_WARNING,
"Found tile attribute and scanline VAR_4. Exr will be interpreted as scanline.\n"); VAR_0->tile_attr.xSize = bytestream2_get_le32(&VAR_0->gb); VAR_0->tile_attr.ySize = bytestream2_get_le32(&VAR_0->gb); VAR_13 = bytestream2_get_byte(&VAR_0->gb); VAR_0->tile_attr.level_mode = VAR_13 & 0x0f; VAR_0->tile_attr.level_round = (VAR_13 >> 4) & 0x0f; if (VAR_0->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN){ avpriv_report_missing_feature(VAR_0->avctx, "Tile level mode %d",
VAR_0->tile_attr.level_mode); return AVERROR_PATCHWELCOME; } if (VAR_0->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) { avpriv_report_missing_feature(VAR_0->avctx, "Tile level round %d",
VAR_0->tile_attr.level_round); return AVERROR_PATCHWELCOME; } continue; } if (bytestream2_get_bytes_left(&VAR_0->gb) <= 9) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Incomplete header\n"); return AVERROR_INVALIDDATA; } for (VAR_3 = 0; VAR_3 < 2; VAR_3++) while (bytestream2_get_byte(&VAR_0->gb) != 0); bytestream2_skip(&VAR_0->gb, bytestream2_get_le32(&VAR_0->gb)); } ff_set_sar(VAR_0->avctx, av_d2q(av_int2float(VAR_5), 255)); if (VAR_0->compression == EXR_UNKN) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Missing compression attribute.\n"); return AVERROR_INVALIDDATA; } if (VAR_0->is_tile) { if (VAR_0->tile_attr.xSize < 1 || VAR_0->tile_attr.ySize < 1) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Invalid tile attribute.\n"); return AVERROR_INVALIDDATA; } } if (bytestream2_get_bytes_left(&VAR_0->gb) <= 0) { av_log(VAR_0->avctx, AV_LOG_ERROR, "Incomplete frame.\n"); return AVERROR_INVALIDDATA; } bytestream2_skip(&VAR_0->gb, 1); return 0; }