/* INTEL CONFIDENTIAL
* Copyright (c) 2012 Intel Corporation.  All rights reserved.
* Copyright (c) Imagination Technologies Limited, UK
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
* Corporation or its suppliers or licensors.  Title to the
* Material remains with Intel Corporation or its suppliers and
* licensors.  The Material contains trade secrets and proprietary
* and confidential information of Intel or its suppliers and
* licensors. The Material is protected by worldwide copyright and
* trade secret laws and treaty provisions.  No part of the Material
* may be used, copied, reproduced, modified, published, uploaded,
* posted, transmitted, distributed, or disclosed in any way without
* Intel's prior express written permission.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you
* by disclosure or delivery of the Materials, either expressly, by
* implication, inducement, estoppel or otherwise. Any license
* under such intellectual property rights must be express and
* approved by Intel in writing.
*
* Authors:
*    Nana Guo <nana.n.guo@intel.com>
*
*/

#include "va/va_tpi.h"
#include "JPEGDecoder.h"
#include "ImageDecoderTrace.h"
#include "JPEGParser.h"
#include <string.h>

#define JPEG_MAX_SETS_HUFFMAN_TABLES 2

#define TABLE_CLASS_DC  0
#define TABLE_CLASS_AC  1
#define TABLE_CLASS_NUM 2

/*
 * Initialize VA API related stuff
 *
 * We will check the return value of  jva_initialize
 * to determine which path will be use (SW or HW)
 *
 */
Decode_Status jdva_initialize (jd_libva_struct * jd_libva_ptr) {
  /*
   * Please note that we won't check the input parameters to follow the
   * convention of libjpeg duo to we need these parameters to do error handling,
   * and if these parameters are invalid, means the whole stack is crashed, so check
   * them here and return false is meaningless, same situation for all internal methods
   * related to VA API
  */
    int va_major_version;
    int va_minor_version;
#if 0
    int va_max_num_profiles, va_max_num_entrypoints, va_max_num_attribs;
    int va_num_profiles,  va_num_entrypoints;

    VAProfile *va_profiles = NULL;
    VAEntrypoint *va_entrypoints = NULL;
#endif
    VAStatus va_status = VA_STATUS_SUCCESS;
    Decode_Status status = DECODE_SUCCESS;
    int index;

    if (jd_libva_ptr->initialized)
        return DECODE_NOT_STARTED;

    jd_libva_ptr->android_display = (Display*)malloc(sizeof(Display));
    if (jd_libva_ptr->android_display == NULL) {
        return DECODE_MEMORY_FAIL;
    }
    jd_libva_ptr->va_display = vaGetDisplay (jd_libva_ptr->android_display);

    if (jd_libva_ptr->va_display == NULL) {
        ETRACE("vaGetDisplay failed.");
        free (jd_libva_ptr->android_display);
        return DECODE_DRIVER_FAIL;
    }
    va_status = vaInitialize(jd_libva_ptr->va_display, &va_major_version, &va_minor_version);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaInitialize failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        goto cleanup;
    }
#if 0
    /*get the max number for profiles/entrypoints/attribs*/
    va_max_num_profiles = vaMaxNumProfiles(jd_libva_ptr->va_display);
    va_max_num_entrypoints = vaMaxNumEntrypoints(jd_libva_ptr->va_display);
    va_max_num_attribs = vaMaxNumConfigAttributes(jd_libva_ptr->va_display);

    va_profiles = malloc (sizeof(VAProfile)*va_max_num_profiles);
    va_entrypoints = malloc(sizeof(VAEntrypoint)*va_max_num_entrypoints);

    if (va_profiles == NULL || va_entrypoints ==NULL) {
        jd_libva_ptr->initialized = TRUE; // make sure we can call into jva_deinitialize()
        jdva_deinitialize (jd_libva_ptr);
        return DECODE_MEMORY_FAIL;
    }

    va_status = vaQueryConfigProfiles (jd_libva_ptr->va_display, va_profiles, &va_num_profiles);

    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaQueryConfigProfiles failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        goto cleanup;
    }

    /*check whether profile is supported*/
    for(index= 0; index < va_num_profiles; index++) {
        if(VAProfileJPEGBaseline == va_profiles[index])
            break;
    }

    if(index == va_num_profiles) {
        WTRACE("Profile not surportted\n");
        status = DECODE_FAIL;
        goto cleanup;

    }

    va_status = vaQueryConfigEntrypoints(jd_libva_ptr->va_display, VAProfileJPEGBaseline, va_entrypoints, &va_num_entrypoints);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaQueryConfigProfiles failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        goto cleanup;
    }
    /* traverse entrypoints arrary to see whether VLD is there */
    for (index = 0; index < va_num_entrypoints; index ++) {
        if (va_entrypoints[index] == VAEntrypointVLD)
            break;
    }
#endif
    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    va_status = vaGetConfigAttributes(jd_libva_ptr->va_display, VAProfileJPEGBaseline, VAEntrypointVLD, &attrib, 1);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaGetConfigAttributes failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        goto cleanup;
    }
    if ((VA_RT_FORMAT_YUV444 & attrib.value) == 0) {
        WTRACE("Format not surportted\n");
        status = DECODE_FAIL;
        goto cleanup;
    }

    va_status = vaCreateConfig(jd_libva_ptr->va_display, VAProfileJPEGBaseline, VAEntrypointVLD, &attrib, 1, &(jd_libva_ptr->va_config));
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaCreateConfig failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        goto cleanup;
    }
    jd_libva_ptr->initialized = TRUE;
    status = DECODE_SUCCESS;

cleanup:
#if 0
    /*free profiles and entrypoints*/
    if (va_profiles)
        free(va_profiles);

    if (va_entrypoints)
        free (va_entrypoints);
#endif
    if (!status) {
        jd_libva_ptr->initialized = TRUE; // make sure we can call into jva_deinitialize()
        jdva_deinitialize (jd_libva_ptr);
        return status;
    }

  return status;
}

void jdva_deinitialize (jd_libva_struct * jd_libva_ptr) {
    if (!(jd_libva_ptr->initialized)) {
        return;
    }

    if (jd_libva_ptr->JPEGParser) {
        free(jd_libva_ptr->JPEGParser);
        jd_libva_ptr->JPEGParser = NULL;
    }

    if (jd_libva_ptr->va_display) {
        vaTerminate(jd_libva_ptr->va_display);
        jd_libva_ptr->va_display = NULL;
    }

    if (jd_libva_ptr->android_display) {
        free(jd_libva_ptr->android_display);
        jd_libva_ptr->android_display = NULL;
    }

    jd_libva_ptr->initialized = FALSE;
    return;
}

Decode_Status jdva_create_resource (jd_libva_struct * jd_libva_ptr) {
    VAStatus va_status = VA_STATUS_SUCCESS;
    Decode_Status status;
    jd_libva_ptr->image_width = jd_libva_ptr->picture_param_buf.picture_width;
    jd_libva_ptr->image_height = jd_libva_ptr->picture_param_buf.picture_height;
    jd_libva_ptr->surface_count = 1;
    jd_libva_ptr->va_surfaces = (VASurfaceID *) malloc(sizeof(VASurfaceID)*jd_libva_ptr->surface_count);
    if (jd_libva_ptr->va_surfaces == NULL) {
        return DECODE_MEMORY_FAIL;
    }
    va_status = vaCreateSurfaces(jd_libva_ptr->va_display, VA_RT_FORMAT_YUV444,
                                    (((jd_libva_ptr->image_width + 7) & (~7)) + 15) & (~15),
                                    (((jd_libva_ptr->image_width + 7) & (~7)) + 15) & (~15),
                                    jd_libva_ptr->va_surfaces,
                                    jd_libva_ptr->surface_count, NULL, 0);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaCreateSurfaces failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        goto cleanup;
    }
    va_status = vaCreateContext(jd_libva_ptr->va_display, jd_libva_ptr->va_config,
                                   (( ( jd_libva_ptr->image_width + 7 ) & ( ~7 )) + 15 ) & ( ~15 ),
                                   ((( jd_libva_ptr->image_height + 7 ) & ( ~7 )) + 15 ) & ( ~15 ),
                                   0,  //VA_PROGRESSIVE
                                   jd_libva_ptr->va_surfaces,
                                   jd_libva_ptr->surface_count, &(jd_libva_ptr->va_context));

    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaCreateContext failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        goto cleanup;

    }
    jd_libva_ptr->resource_allocated = TRUE;
    return status;
cleanup:

    if (jd_libva_ptr->va_surfaces) {
        free (jd_libva_ptr->va_surfaces);
        jd_libva_ptr->va_surfaces = NULL;
    }
    jdva_deinitialize (jd_libva_ptr);

    return status;
}

Decode_Status jdva_release_resource (jd_libva_struct * jd_libva_ptr) {
    Decode_Status status = DECODE_SUCCESS;
    VAStatus va_status = VA_STATUS_SUCCESS;

    if (!(jd_libva_ptr->resource_allocated)) {
        return status;
    }

    if (!(jd_libva_ptr->va_display)) {
        return status; //most likely the resource are already released and HW jpeg is deinitialize, return directly
    }

  /*
   * It is safe to destroy Surface/Config/Context severl times
   * and it is also safe even their value is NULL
   */

    va_status = vaDestroySurfaces(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces, jd_libva_ptr->surface_count);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaDestroySurfaces failed. va_status = 0x%x", va_status);
        return DECODE_DRIVER_FAIL;
    }

    if (jd_libva_ptr->va_surfaces) {
        free (jd_libva_ptr->va_surfaces);
        jd_libva_ptr->va_surfaces = NULL;
    }

    va_status = vaDestroyConfig(jd_libva_ptr->va_display, jd_libva_ptr->va_config);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaDestroyConfig failed. va_status = 0x%x", va_status);
        return DECODE_DRIVER_FAIL;
    }

    jd_libva_ptr->va_config = NULL;

    va_status = vaDestroyContext(jd_libva_ptr->va_display, jd_libva_ptr->va_context);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaDestroyContext failed. va_status = 0x%x", va_status);
        return DECODE_DRIVER_FAIL;
    }

    jd_libva_ptr->va_context = NULL;

    jd_libva_ptr->resource_allocated = FALSE;

    return va_status;
}

Decode_Status jdva_decode (jd_libva_struct * jd_libva_ptr, uint8_t* buf) {
    Decode_Status status = DECODE_SUCCESS;
    VAStatus va_status = VA_STATUS_SUCCESS;
    VABufferID desc_buf[5];
    uint32_t bitstream_buffer_size;
    uint32_t scan_idx = 0;
    uint32_t buf_idx = 0;
    uint32_t chopping = VA_SLICE_DATA_FLAG_ALL;
    uint32_t bytes_remaining = jd_libva_ptr->file_size;
    uint32_t src_offset = 0;
    bitstream_buffer_size = 1024*512*5;

    va_status = vaBeginPicture(jd_libva_ptr->va_display, jd_libva_ptr->va_context, jd_libva_ptr->va_surfaces[0]);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaBeginPicture failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        return status;
    }
    va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VAPictureParameterBufferType, sizeof(VAPictureParameterBufferJPEG), 1, &jd_libva_ptr->picture_param_buf, &desc_buf[buf_idx]);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        return status;
    }
    buf_idx++;
    va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VAIQMatrixBufferType, sizeof(VAIQMatrixParameterBufferJPEG), 1, &jd_libva_ptr->qmatrix_buf, &desc_buf[buf_idx]);

    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        return status;
    }
    buf_idx++;
    va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VAHuffmanTableBufferType, sizeof(VAHuffmanTableParameterBufferJPEG), 1, &jd_libva_ptr->hufman_table_buf, &desc_buf[buf_idx]);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        return status;
    }
    buf_idx++;
    do {
        /* Get Bitstream Buffer */
        uint32_t bytes = ( bytes_remaining < bitstream_buffer_size ) ? bytes_remaining : bitstream_buffer_size;
        bytes_remaining -= bytes;
        /* Get Slice Control Buffer */
        VASliceParameterBufferJPEG dest_scan_ctrl[JPEG_MAX_COMPONENTS];
        uint32_t src_idx;
        uint32_t dest_idx = 0;
        memset(dest_scan_ctrl, 0, sizeof(dest_scan_ctrl));
        for (src_idx = scan_idx; src_idx < jd_libva_ptr->scan_ctrl_count ; src_idx++) {
            if (jd_libva_ptr->slice_param_buf[ src_idx ].slice_data_offset) {
                /* new scan, reset state machine */
                chopping = VA_SLICE_DATA_FLAG_ALL;
                fprintf(stderr,"Scan:%i FileOffset:%x Bytes:%x \n", src_idx,
                    jd_libva_ptr->slice_param_buf[ src_idx ].slice_data_offset,
                    jd_libva_ptr->slice_param_buf[ src_idx ].slice_data_size );
                /* does the slice end in the buffer */
                if (jd_libva_ptr->slice_param_buf[ src_idx ].slice_data_offset + jd_libva_ptr->slice_param_buf[ src_idx ].slice_data_size > bytes + src_offset) {
                    chopping = VA_SLICE_DATA_FLAG_BEGIN;
                }
            } else {
                if (jd_libva_ptr->slice_param_buf[ src_idx ].slice_data_size > bytes) {
                    chopping = VA_SLICE_DATA_FLAG_MIDDLE;
                } else {
                    if ((chopping == VA_SLICE_DATA_FLAG_BEGIN) || (chopping == VA_SLICE_DATA_FLAG_MIDDLE)) {
                        chopping = VA_SLICE_DATA_FLAG_END;
                    }
                }
            }
            dest_scan_ctrl[dest_idx].slice_data_flag = chopping;
            dest_scan_ctrl[dest_idx].slice_data_offset = ((chopping == VA_SLICE_DATA_FLAG_ALL) ||      (chopping == VA_SLICE_DATA_FLAG_BEGIN) )?
jd_libva_ptr->slice_param_buf[ src_idx ].slice_data_offset - src_offset : 0;

            const int32_t bytes_in_seg = bytes - dest_scan_ctrl[dest_idx].slice_data_offset;
            const uint32_t scan_data = (bytes_in_seg < jd_libva_ptr->slice_param_buf[src_idx].slice_data_size) ? bytes_in_seg : jd_libva_ptr->slice_param_buf[src_idx].slice_data_size ;
            jd_libva_ptr->slice_param_buf[src_idx].slice_data_offset = 0;
            jd_libva_ptr->slice_param_buf[src_idx].slice_data_size -= scan_data;
            dest_scan_ctrl[dest_idx].slice_data_size = scan_data;
            dest_scan_ctrl[dest_idx].num_components = jd_libva_ptr->slice_param_buf[src_idx].num_components;
            dest_scan_ctrl[dest_idx].restart_interval = jd_libva_ptr->slice_param_buf[src_idx].restart_interval;
            memcpy(&dest_scan_ctrl[dest_idx].components, & jd_libva_ptr->slice_param_buf[ src_idx ].components,
                sizeof(jd_libva_ptr->slice_param_buf[ src_idx ].components) );
            dest_idx++;
            if ((chopping == VA_SLICE_DATA_FLAG_ALL) || (chopping == VA_SLICE_DATA_FLAG_END)) { /* all good good */
            } else {
                break;
            }
        }
        scan_idx = src_idx;
        /* Get Slice Control Buffer */
        va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VASliceParameterBufferType, sizeof(VASliceParameterBufferJPEG) * dest_idx, 1, dest_scan_ctrl, &desc_buf[buf_idx]);
        if (va_status != VA_STATUS_SUCCESS) {
            ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
            status = DECODE_DRIVER_FAIL;
            return status;
        }
        buf_idx++;
        va_status = vaCreateBuffer(jd_libva_ptr->va_display, jd_libva_ptr->va_context, VASliceDataBufferType, bytes, 1, &jd_libva_ptr->bitstream_buf[ src_offset ], &desc_buf[buf_idx]);
        buf_idx++;
        if (va_status != VA_STATUS_SUCCESS) {
            ETRACE("vaCreateBuffer failed. va_status = 0x%x", va_status);
            status = DECODE_DRIVER_FAIL;
            return status;
        }
        va_status = vaRenderPicture( jd_libva_ptr->va_display, jd_libva_ptr->va_context, desc_buf, buf_idx);
        if (va_status != VA_STATUS_SUCCESS) {
            ETRACE("vaRenderPicture failed. va_status = 0x%x", va_status);
            status = DECODE_DRIVER_FAIL;
            return status;
        }
        buf_idx = 0;

        src_offset += bytes;
    } while (bytes_remaining);

    va_status = vaEndPicture(jd_libva_ptr->va_display, jd_libva_ptr->va_context);
    if (va_status != VA_STATUS_SUCCESS) {
        ETRACE("vaRenderPicture failed. va_status = 0x%x", va_status);
        status = DECODE_DRIVER_FAIL;
        return status;
    }

    va_status = vaSyncSurface(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces[0]);
    if (va_status != VA_STATUS_SUCCESS) {
        WTRACE("vaSyncSurface failed. va_status = 0x%x", va_status);
    }
#if 0
    uint8_t* rgb_buf;
    int32_t data_len = 0;
    uint32_t surface_width, surface_height;
    surface_width = (( ( jd_libva_ptr->image_width + 7 ) & ( ~7 )) + 15 ) & ( ~15 );
    surface_height = (( ( jd_libva_ptr->image_height + 7 ) & ( ~7 )) + 15 ) & ( ~15 );

    rgb_buf = (uint8_t*) malloc((surface_width * surface_height) << 2);
    if(rgb_buf == NULL){
        return DECODE_MEMORY_FAIL;
    }
    va_status = vaPutSurfaceBuf(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces[0], rgb_buf, &data_len, 0, 0, surface_width, surface_height, 0, 0, surface_width, surface_height, NULL, 0, 0);

    buf = rgb_buf;
// dump RGB data
    {
        FILE *pf_tmp = fopen("img_out.rgb", "wb");
        if(pf_tmp == NULL)
            ETRACE("Open file error");
        fwrite(rgb_buf, 1, surface_width * surface_height * 4, pf_tmp);
        fclose(pf_tmp);
    }
#endif
#if 0
    va_status = vaDeriveImage(jd_libva_ptr->va_display, jd_libva_ptr->va_surfaces[0], &(jd_libva_ptr->surface_image));
    if (va_status != VA_STATUS_SUCCESS) {
        ERREXIT1 (cinfo, JERR_VA_DRIVEIMAGE, va_status);
    }

    va_status = vaMapBuffer(jd_libva_ptr->va_display, jd_libva_ptr->surface_image.buf, (void **)& (jd_libva_ptr->image_buf));
    if (va_status != VA_STATUS_SUCCESS) {
        ERREXIT1 (cinfo, JERR_VA_MAPBUFFER, va_status);
    }

    va_status = vaUnmapBuffer(jd_libva_ptr->va_display, jd_libva_ptr->surface_image.buf);
    if (va_status != VA_STATUS_SUCCESS) {
        ERREXIT1(cinfo, JERR_VA_MAPBUFFER, va_status);
    }

    va_status = vaDestroyImage(jd_libva_ptr->va_display, jd_libva_ptr->surface_image.image_id);

    if (va_status != VA_STATUS_SUCCESS) {
        ERREXIT1 (cinfo, JERR_VA_MAPBUFFER, va_status);
    }
#endif
    return status;
}

Decode_Status parseBitstream(jd_libva_struct * jd_libva_ptr) {
    uint32_t component_order = 0 ;
    uint32_t dqt_ind = 0;
    uint32_t dht_ind = 0;
    uint32_t scan_ind = 0;
    boolean frame_marker_found = FALSE;

    uint8_t marker = jd_libva_ptr->JPEGParser->getNextMarker(jd_libva_ptr->JPEGParser);

    while (marker != CODE_EOI) {
        switch (marker) {
            // If the marker is an APP marker skip over the data
            case CODE_APP0:
            case CODE_APP1:
            case CODE_APP2:
            case CODE_APP3:
            case CODE_APP4:
            case CODE_APP5:
            case CODE_APP6:
            case CODE_APP7:
            case CODE_APP8:
            case CODE_APP9:
            case CODE_APP10:
            case CODE_APP11:
            case CODE_APP12:
            case CODE_APP13:
            case CODE_APP14:
            case CODE_APP15: {

                uint32_t bytes_to_burn = jd_libva_ptr->JPEGParser->readBytes(jd_libva_ptr->JPEGParser, 2) - 2;
                jd_libva_ptr->JPEGParser->burnBytes(jd_libva_ptr->JPEGParser, bytes_to_burn);
                    break;
            }
            // Store offset to DQT data to avoid parsing bitstream in user mode
            case CODE_DQT: {
                jd_libva_ptr->dqt_byte_offset[dqt_ind] = jd_libva_ptr->JPEGParser->getByteOffset(jd_libva_ptr->JPEGParser);
                dqt_ind++;
                uint32_t bytes_to_burn = jd_libva_ptr->JPEGParser->readBytes( jd_libva_ptr->JPEGParser, 2 ) - 2;
                jd_libva_ptr->JPEGParser->burnBytes( jd_libva_ptr->JPEGParser, bytes_to_burn );
                break;
            }
            // Throw exception for all SOF marker other than SOF0
            case CODE_SOF1:
            case CODE_SOF2:
            case CODE_SOF3:
            case CODE_SOF5:
            case CODE_SOF6:
            case CODE_SOF7:
            case CODE_SOF8:
            case CODE_SOF9:
            case CODE_SOF10:
            case CODE_SOF11:
            case CODE_SOF13:
            case CODE_SOF14:
            case CODE_SOF15: {
                fprintf(stderr, "ERROR: unsupport SOF\n");
                break;
            }
            // Parse component information in SOF marker
            case CODE_SOF_BASELINE: {
                frame_marker_found = TRUE;

                jd_libva_ptr->JPEGParser->burnBytes(jd_libva_ptr->JPEGParser, 2); // Throw away frame header length
                jd_libva_ptr->picture_param_buf.sample_precision = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);
                if (jd_libva_ptr->picture_param_buf.sample_precision != 8) {
                    return DECODE_PARSER_FAIL;
                }
                // Extract pic width and height
                jd_libva_ptr->picture_param_buf.picture_height = jd_libva_ptr->JPEGParser->readBytes(jd_libva_ptr->JPEGParser, 2);
                jd_libva_ptr->picture_param_buf.picture_width = jd_libva_ptr->JPEGParser->readBytes(jd_libva_ptr->JPEGParser, 2);
                jd_libva_ptr->picture_param_buf.num_components = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);

                if (jd_libva_ptr->picture_param_buf.num_components > JPEG_MAX_COMPONENTS) {
                    return DECODE_PARSER_FAIL;
                }
                uint8_t comp_ind;
                for (comp_ind = 0; comp_ind < jd_libva_ptr->picture_param_buf.num_components; comp_ind++) {
                    jd_libva_ptr->picture_param_buf.components[comp_ind].component_id = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);

                    uint8_t hv_sampling = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);
                    jd_libva_ptr->picture_param_buf.components[comp_ind].h_sampling_factor = hv_sampling >> 4;
                    jd_libva_ptr->picture_param_buf.components[comp_ind].v_sampling_factor = hv_sampling & 0xf;
                    jd_libva_ptr->picture_param_buf.components[comp_ind].quantiser_table_selector = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);
                }


                break;
            }
            // Store offset to DHT data to avoid parsing bitstream in user mode
            case CODE_DHT: {
                jd_libva_ptr->dht_byte_offset[dht_ind] = jd_libva_ptr->JPEGParser->getByteOffset(jd_libva_ptr->JPEGParser);
                dht_ind++;
                uint32_t bytes_to_burn = jd_libva_ptr->JPEGParser->readBytes(jd_libva_ptr->JPEGParser, 2) - 2;
                jd_libva_ptr->JPEGParser->burnBytes(jd_libva_ptr->JPEGParser,  bytes_to_burn );
                break;
            }
            // Parse component information in SOS marker
            case CODE_SOS: {
                jd_libva_ptr->JPEGParser->burnBytes(jd_libva_ptr->JPEGParser, 2);
                uint32_t component_in_scan = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);
                uint8_t comp_ind;

                for (comp_ind = 0; comp_ind < component_in_scan; comp_ind++) {
                    uint8_t comp_id = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);
                    uint8_t comp_data_ind;
                    for (comp_data_ind = 0; comp_data_ind < jd_libva_ptr->picture_param_buf.num_components; comp_data_ind++) {
                        if (comp_id == jd_libva_ptr->picture_param_buf.components[comp_data_ind].component_id) {
                            jd_libva_ptr->slice_param_buf[scan_ind].components[comp_ind].component_selector = comp_data_ind;
                            break;
                        }
                    }
                    uint8_t huffman_tables = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);
                    jd_libva_ptr->slice_param_buf[scan_ind].components[comp_ind].dc_table_selector = huffman_tables >> 4;
                    jd_libva_ptr->slice_param_buf[scan_ind].components[comp_ind].ac_table_selector = huffman_tables & 0xf;
                }
                uint32_t curr_byte = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser); // Ss
                if (curr_byte != 0) {
                    return DECODE_PARSER_FAIL;
                }
                curr_byte = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);  // Se
                if (curr_byte != 0x3f) {
                    return DECODE_PARSER_FAIL;
                }
                curr_byte = jd_libva_ptr->JPEGParser->readNextByte(jd_libva_ptr->JPEGParser);  // Ah, Al
                if (curr_byte != 0) {
                    return DECODE_PARSER_FAIL;
                }
                // Set slice control variables needed
                jd_libva_ptr->slice_param_buf[scan_ind].slice_data_offset = jd_libva_ptr->JPEGParser->getByteOffset(jd_libva_ptr->JPEGParser);
                jd_libva_ptr->slice_param_buf[scan_ind].num_components = component_in_scan;
                if (scan_ind) {
                    /* If there is more than one scan, the slice for all but the final scan should only run up to the beginning of the next scan */
                    jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_size =
                        (jd_libva_ptr->slice_param_buf[scan_ind].slice_data_offset - jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_offset );;
                    }
                    scan_ind++;
                    jd_libva_ptr->scan_ctrl_count++;   // gsDXVA2Globals.uiScanCtrlCount
                    break;
                }
            case CODE_DRI: {
                uint32_t size =  jd_libva_ptr->JPEGParser->readBytes(jd_libva_ptr->JPEGParser, 2);
                jd_libva_ptr->slice_param_buf[scan_ind].restart_interval =  jd_libva_ptr->JPEGParser->readBytes(jd_libva_ptr->JPEGParser, 2);
                jd_libva_ptr->JPEGParser->burnBytes(jd_libva_ptr->JPEGParser, (size - 4));
                break;
            }
            default:
                break;
        }

        marker = jd_libva_ptr->JPEGParser->getNextMarker(jd_libva_ptr->JPEGParser);
    }

    jd_libva_ptr->quant_tables_num = dqt_ind;
    jd_libva_ptr->huffman_tables_num = dht_ind;

    /* The slice for the last scan should run up to the end of the picture */
    jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_size = (jd_libva_ptr->file_size - jd_libva_ptr->slice_param_buf[scan_ind - 1].slice_data_offset);

    // throw AppException if SOF0 isn't found
    if (!frame_marker_found) {
        ETRACE("EEORR: Reached end of bitstream while trying to parse headers\n");
        return DECODE_PARSER_FAIL;
    }

    parseTableData(jd_libva_ptr);

    return DECODE_SUCCESS;

}

Decode_Status parseTableData(jd_libva_struct * jd_libva_ptr) {
    Decode_Status status;
    CJPEGParse* parser = (CJPEGParse*)malloc(sizeof(CJPEGParse));
    if (parser == NULL)
        return DECODE_MEMORY_FAIL;

    parserInitialize(parser, jd_libva_ptr->bitstream_buf, jd_libva_ptr->file_size);

    // Parse Quant tables
    memset(&jd_libva_ptr->qmatrix_buf, 0, sizeof(jd_libva_ptr->qmatrix_buf));
    uint32_t dqt_ind;
    for (dqt_ind = 0; dqt_ind < jd_libva_ptr->quant_tables_num; dqt_ind++) {
        if (parser->setByteOffset(parser, jd_libva_ptr->dqt_byte_offset[dqt_ind])) {
            // uint32_t uiTableBytes = parser->readBytes( 2 ) - 2;
            uint32_t table_bytes = parser->readBytes( parser, 2 ) - 2;
            do {
                uint32_t table_info = parser->readNextByte(parser);
                table_bytes--;
                uint32_t table_length = table_bytes > 64 ? 64 : table_bytes;
                uint32_t table_precision = table_info >> 4;
                if (table_precision != 0) {
                    return DECODE_PARSER_FAIL;
                }
                uint32_t table_id = table_info & 0xf;
                if (table_id >= JPEG_MAX_QUANT_TABLES) {
                    return DECODE_PARSER_FAIL;
                }
                jd_libva_ptr->qmatrix_buf.load_quantiser_table[dqt_ind] = table_id;

                // Pull Quant table data from bitstream
                uint32_t byte_ind;
                for (byte_ind = 0; byte_ind < table_length; byte_ind++) {
                    jd_libva_ptr->qmatrix_buf.quantiser_table[table_id][byte_ind] = parser->readNextByte(parser);
                }
                table_bytes -= table_length;
            } while (table_bytes);
        }
    }

    // Parse Huffman tables
    memset(&jd_libva_ptr->hufman_table_buf, 0, sizeof(jd_libva_ptr->hufman_table_buf));
    uint32_t dht_ind;
    for (dht_ind = 0; dht_ind < jd_libva_ptr->huffman_tables_num; dht_ind++) {
        if (parser->setByteOffset(parser, jd_libva_ptr->dht_byte_offset[dht_ind])) {
            uint32_t table_bytes = parser->readBytes( parser, 2 ) - 2;
            do {
                uint32_t table_info = parser->readNextByte(parser);
                table_bytes--;
                uint32_t table_class = table_info >> 4; // Identifies whether the table is for AC or DC
                if (table_class >= TABLE_CLASS_NUM) {
                    return DECODE_PARSER_FAIL;
                }
                uint32_t table_id = table_info & 0xf;
                if (table_id >= JPEG_MAX_SETS_HUFFMAN_TABLES) {
                    return DECODE_PARSER_FAIL;
                }
                if (table_class == 0) {
                    uint8_t* bits = parser->getCurrentIndex(parser);
                    // Find out the number of entries in the table
                    uint32_t table_entries = 0;
                    uint32_t bit_ind;
                    for (bit_ind = 0; bit_ind < 16; bit_ind++) {
                        jd_libva_ptr->hufman_table_buf.huffman_table[table_id].num_dc_codes[bit_ind] = bits[bit_ind];
                        table_entries += jd_libva_ptr->hufman_table_buf.huffman_table[table_id].num_dc_codes[bit_ind];
                    }

                    // Create table of code values
                    parser->burnBytes(parser, 16);
                    table_bytes -= 16;
                    uint32_t tbl_ind;
                    for (tbl_ind = 0; tbl_ind < table_entries; tbl_ind++) {
                        jd_libva_ptr->hufman_table_buf.huffman_table[table_id].dc_values[tbl_ind] = parser->readNextByte(parser);
                        table_bytes--;
                    }

                } else { // for AC class
                    uint8_t* bits = parser->getCurrentIndex(parser);
                    // Find out the number of entries in the table
                    uint32_t table_entries = 0;
                    uint32_t bit_ind;
                    for (bit_ind = 0; bit_ind < 16; bit_ind++) {
                        jd_libva_ptr->hufman_table_buf.huffman_table[table_id].num_ac_codes[bit_ind] = bits[bit_ind];
                        table_entries += jd_libva_ptr->hufman_table_buf.huffman_table[table_id].num_ac_codes[bit_ind];
                    }

                    // Create table of code values
                    parser->burnBytes(parser, 16);
                    table_bytes -= 16;
                    uint32_t tbl_ind;
                    for (tbl_ind = 0; tbl_ind < table_entries; tbl_ind++) {
                        jd_libva_ptr->hufman_table_buf.huffman_table[table_id].ac_values[tbl_ind] = parser->readNextByte(parser);
                        table_bytes--;
                    }
                }//end of else

            } while (table_bytes);
        }
    }

    if (parser) {
        free(parser);
        parser = NULL;
    }
    return DECODE_SUCCESS;
}

