/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "TextDescriptions.h"
#include <media/stagefright/Utils.h>
#include <media/stagefright/MediaErrors.h>

namespace android {

TextDescriptions::TextDescriptions() {
}

status_t TextDescriptions::getParcelOfDescriptions(
        const uint8_t *data, ssize_t size,
        uint32_t flags, int timeMs, Parcel *parcel) {
    parcel->freeData();

    if (flags & IN_BAND_TEXT_3GPP) {
        if (flags & GLOBAL_DESCRIPTIONS) {
            return extract3GPPGlobalDescriptions(data, size, parcel);
        } else if (flags & LOCAL_DESCRIPTIONS) {
            return extract3GPPLocalDescriptions(data, size, timeMs, parcel);
        }
    } else if (flags & OUT_OF_BAND_TEXT_SRT) {
        if (flags & LOCAL_DESCRIPTIONS) {
            return extractSRTLocalDescriptions(data, size, timeMs, parcel);
        }
    }

    return ERROR_UNSUPPORTED;
}

// Parse the SRT text sample, and store the timing and text sample in a Parcel.
// The Parcel will be sent to MediaPlayer.java through event, and will be
// parsed in TimedText.java.
status_t TextDescriptions::extractSRTLocalDescriptions(
        const uint8_t *data, ssize_t size, int timeMs, Parcel *parcel) {
    parcel->writeInt32(KEY_LOCAL_SETTING);
    parcel->writeInt32(KEY_START_TIME);
    parcel->writeInt32(timeMs);

    parcel->writeInt32(KEY_STRUCT_TEXT);
    // write the size of the text sample
    parcel->writeInt32(size);
    // write the text sample as a byte array
    parcel->writeInt32(size);
    parcel->write(data, size);

    return OK;
}

// Extract the local 3GPP display descriptions. 3GPP local descriptions
// are appended to the text sample if any. The descriptions could include
// information such as text styles, highlights, karaoke and so on. They
// are contained in different boxes, such as 'styl' box contains text
// styles, and 'krok' box contains karaoke timing and positions.
status_t TextDescriptions::extract3GPPLocalDescriptions(
        const uint8_t *data, ssize_t size,
        int timeMs, Parcel *parcel) {

    parcel->writeInt32(KEY_LOCAL_SETTING);

    // write start time to display this text sample
    parcel->writeInt32(KEY_START_TIME);
    parcel->writeInt32(timeMs);

    if (size < 2) {
        return OK;
    }
    ssize_t textLen = (*data) << 8 | (*(data + 1));

    if (size < textLen + 2) {
        return OK;
    }

    // write text sample length and text sample itself
    parcel->writeInt32(KEY_STRUCT_TEXT);
    parcel->writeInt32(textLen);
    parcel->writeInt32(textLen);
    parcel->write(data + 2, textLen);

    if (size > textLen + 2) {
        data += (textLen + 2);
        size -= (textLen + 2);
    } else {
        return OK;
    }

    while (size >= 8) {
        const uint8_t *tmpData = data;
        ssize_t chunkSize = U32_AT(tmpData);      // size includes size and type
        uint32_t chunkType = U32_AT(tmpData + 4);

        if (chunkSize <= 8 || chunkSize > size) {
            return OK;
        }

        size_t remaining = chunkSize - 8;

        tmpData += 8;

        switch(chunkType) {
            // 'styl' box specifies the style of the text.
            case FOURCC('s', 't', 'y', 'l'):
            {
                if (remaining < 2) {
                    return OK;
                }
                size_t dataPos = parcel->dataPosition();
                uint16_t count = U16_AT(tmpData);

                tmpData += 2;
                remaining -= 2;

                for (int i = 0; i < count; i++) {
                    if (remaining < 12) {
                        // roll back
                        parcel->setDataPosition(dataPos);
                        return OK;
                    }
                    parcel->writeInt32(KEY_STRUCT_STYLE_LIST);
                    parcel->writeInt32(KEY_START_CHAR);
                    parcel->writeInt32(U16_AT(tmpData));

                    parcel->writeInt32(KEY_END_CHAR);
                    parcel->writeInt32(U16_AT(tmpData + 2));

                    parcel->writeInt32(KEY_FONT_ID);
                    parcel->writeInt32(U16_AT(tmpData + 4));

                    parcel->writeInt32(KEY_STYLE_FLAGS);
                    parcel->writeInt32(*(tmpData + 6));

                    parcel->writeInt32(KEY_FONT_SIZE);
                    parcel->writeInt32(*(tmpData + 7));

                    parcel->writeInt32(KEY_TEXT_COLOR_RGBA);
                    uint32_t rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16
                        | *(tmpData + 10) << 8 | *(tmpData + 11);
                    parcel->writeInt32(rgba);

                    tmpData += 12;
                    remaining -= 12;
                }

                break;
            }
            // 'krok' box. The number of highlight events is specified, and each
            // event is specified by a starting and ending char offset and an end
            // time for the event.
            case FOURCC('k', 'r', 'o', 'k'):
            {
                if (remaining < 6) {
                    return OK;
                }
                size_t dataPos = parcel->dataPosition();

                parcel->writeInt32(KEY_STRUCT_KARAOKE_LIST);

                int startTime = U32_AT(tmpData);
                uint16_t count = U16_AT(tmpData + 4);
                parcel->writeInt32(count);

                tmpData += 6;
                remaining -= 6;
                int lastEndTime = 0;

                for (int i = 0; i < count; i++) {
                    if (remaining < 8) {
                        // roll back
                        parcel->setDataPosition(dataPos);
                        return OK;
                    }
                    parcel->writeInt32(startTime + lastEndTime);

                    lastEndTime = U32_AT(tmpData);
                    parcel->writeInt32(lastEndTime);

                    parcel->writeInt32(U16_AT(tmpData + 4));
                    parcel->writeInt32(U16_AT(tmpData + 6));

                    tmpData += 8;
                    remaining -= 8;
                }

                break;
            }
            // 'hlit' box specifies highlighted text
            case FOURCC('h', 'l', 'i', 't'):
            {
                if (remaining < 4) {
                    return OK;
                }

                parcel->writeInt32(KEY_STRUCT_HIGHLIGHT_LIST);

                // the start char offset to highlight
                parcel->writeInt32(U16_AT(tmpData));
                // the last char offset to highlight
                parcel->writeInt32(U16_AT(tmpData + 2));

                tmpData += 4;
                remaining -= 4;
                break;
            }
            // 'hclr' box specifies the RGBA color: 8 bits each of
            // red, green, blue, and an alpha(transparency) value
            case FOURCC('h', 'c', 'l', 'r'):
            {
                if (remaining < 4) {
                    return OK;
                }
                parcel->writeInt32(KEY_HIGHLIGHT_COLOR_RGBA);

                uint32_t rgba = *(tmpData) << 24 | *(tmpData + 1) << 16
                    | *(tmpData + 2) << 8 | *(tmpData + 3);
                parcel->writeInt32(rgba);

                tmpData += 4;
                remaining -= 4;
                break;
            }
            // 'dlay' box specifies a delay after a scroll in and/or
            // before scroll out.
            case FOURCC('d', 'l', 'a', 'y'):
            {
                if (remaining < 4) {
                    return OK;
                }
                parcel->writeInt32(KEY_SCROLL_DELAY);

                uint32_t delay = *(tmpData) << 24 | *(tmpData + 1) << 16
                    | *(tmpData + 2) << 8 | *(tmpData + 3);
                parcel->writeInt32(delay);

                tmpData += 4;
                remaining -= 4;
                break;
            }
            // 'href' box for hyper text link
            case FOURCC('h', 'r', 'e', 'f'):
            {
                if (remaining < 5) {
                    return OK;
                }

                size_t dataPos = parcel->dataPosition();

                parcel->writeInt32(KEY_STRUCT_HYPER_TEXT_LIST);

                // the start offset of the text to be linked
                parcel->writeInt32(U16_AT(tmpData));
                // the end offset of the text
                parcel->writeInt32(U16_AT(tmpData + 2));

                // the number of bytes in the following URL
                size_t len = *(tmpData + 4);
                parcel->writeInt32(len);

                remaining -= 5;

                if (remaining  < len) {
                    parcel->setDataPosition(dataPos);
                    return OK;
                }
                // the linked-to URL
                parcel->writeInt32(len);
                parcel->write(tmpData + 5, len);

                tmpData += (5 + len);
                remaining -= len;

                if (remaining  < 1) {
                    parcel->setDataPosition(dataPos);
                    return OK;
                }

                // the number of bytes in the following "alt" string
                len = *tmpData;
                parcel->writeInt32(len);

                tmpData += 1;
                remaining -= 1;
                if (remaining  < len) {
                    parcel->setDataPosition(dataPos);
                    return OK;
                }

                // an "alt" string for user display
                parcel->writeInt32(len);
                parcel->write(tmpData, len);

                tmpData += 1;
                remaining -= 1;
                break;
            }
            // 'tbox' box to indicate the position of the text with values
            // of top, left, bottom and right
            case FOURCC('t', 'b', 'o', 'x'):
            {
                if (remaining < 8) {
                    return OK;
                }
                parcel->writeInt32(KEY_STRUCT_TEXT_POS);
                parcel->writeInt32(U16_AT(tmpData));
                parcel->writeInt32(U16_AT(tmpData + 2));
                parcel->writeInt32(U16_AT(tmpData + 4));
                parcel->writeInt32(U16_AT(tmpData + 6));

                tmpData += 8;
                remaining -= 8;
                break;
            }
            // 'blnk' to specify the char range to be blinked
            case FOURCC('b', 'l', 'n', 'k'):
            {
                if (remaining < 4) {
                    return OK;
                }

                parcel->writeInt32(KEY_STRUCT_BLINKING_TEXT_LIST);

                // start char offset
                parcel->writeInt32(U16_AT(tmpData));
                // end char offset
                parcel->writeInt32(U16_AT(tmpData + 2));

                tmpData += 4;
                remaining -= 4;
                break;
            }
            // 'twrp' box specifies text wrap behavior. If the value if 0x00,
            // then no wrap. If it's 0x01, then automatic 'soft' wrap is enabled.
            // 0x02-0xff are reserved.
            case FOURCC('t', 'w', 'r', 'p'):
            {
                if (remaining < 1) {
                    return OK;
                }
                parcel->writeInt32(KEY_WRAP_TEXT);
                parcel->writeInt32(*tmpData);

                tmpData += 1;
                remaining -= 1;
                break;
            }
            default:
            {
                break;
            }
        }

        data += chunkSize;
        size -= chunkSize;
    }

    return OK;
}

// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a Parcel
status_t TextDescriptions::extract3GPPGlobalDescriptions(
        const uint8_t *data, ssize_t size, Parcel *parcel) {

    parcel->writeInt32(KEY_GLOBAL_SETTING);

    while (size >= 8) {
        ssize_t chunkSize = U32_AT(data);
        uint32_t chunkType = U32_AT(data + 4);
        const uint8_t *tmpData = data;
        tmpData += 8;
        size_t remaining = size - 8;

        if (size < chunkSize) {
            return OK;
        }
        switch(chunkType) {
            case FOURCC('t', 'x', '3', 'g'):
            {
                if (remaining < 18) { // 8 just below, and another 10 a little further down
                    return OK;
                }
                tmpData += 8; // skip the first 8 bytes
                remaining -=8;
                parcel->writeInt32(KEY_DISPLAY_FLAGS);
                parcel->writeInt32(U32_AT(tmpData));

                parcel->writeInt32(KEY_STRUCT_JUSTIFICATION);
                parcel->writeInt32(tmpData[4]);
                parcel->writeInt32(tmpData[5]);

                parcel->writeInt32(KEY_BACKGROUND_COLOR_RGBA);
                uint32_t rgba = *(tmpData + 6) << 24 | *(tmpData + 7) << 16
                    | *(tmpData + 8) << 8 | *(tmpData + 9);
                parcel->writeInt32(rgba);

                tmpData += 10;
                remaining -= 10;

                if (remaining < 8) {
                    return OK;
                }
                parcel->writeInt32(KEY_STRUCT_TEXT_POS);
                parcel->writeInt32(U16_AT(tmpData));
                parcel->writeInt32(U16_AT(tmpData + 2));
                parcel->writeInt32(U16_AT(tmpData + 4));
                parcel->writeInt32(U16_AT(tmpData + 6));

                tmpData += 8;
                remaining -= 8;

                if (remaining < 12) {
                    return OK;
                }
                parcel->writeInt32(KEY_STRUCT_STYLE_LIST);
                parcel->writeInt32(KEY_START_CHAR);
                parcel->writeInt32(U16_AT(tmpData));

                parcel->writeInt32(KEY_END_CHAR);
                parcel->writeInt32(U16_AT(tmpData + 2));

                parcel->writeInt32(KEY_FONT_ID);
                parcel->writeInt32(U16_AT(tmpData + 4));

                parcel->writeInt32(KEY_STYLE_FLAGS);
                parcel->writeInt32(*(tmpData + 6));

                parcel->writeInt32(KEY_FONT_SIZE);
                parcel->writeInt32(*(tmpData + 7));

                parcel->writeInt32(KEY_TEXT_COLOR_RGBA);
                rgba = *(tmpData + 8) << 24 | *(tmpData + 9) << 16
                    | *(tmpData + 10) << 8 | *(tmpData + 11);
                parcel->writeInt32(rgba);

                tmpData += 12;
                remaining -= 12;

                if (remaining < 2) {
                    return OK;
                }

                size_t dataPos = parcel->dataPosition();

                parcel->writeInt32(KEY_STRUCT_FONT_LIST);
                uint16_t count = U16_AT(tmpData);
                parcel->writeInt32(count);

                tmpData += 2;
                remaining -= 2;

                for (int i = 0; i < count; i++) {
                    if (remaining < 3) {
                        // roll back
                        parcel->setDataPosition(dataPos);
                        return OK;
                    }
                    // font ID
                    parcel->writeInt32(U16_AT(tmpData));

                    // font name length
                    parcel->writeInt32(*(tmpData + 2));

                    size_t len = *(tmpData + 2);

                    tmpData += 3;
                    remaining -= 3;

                    if (remaining < len) {
                        // roll back
                        parcel->setDataPosition(dataPos);
                        return OK;
                    }

                    parcel->write(tmpData, len);
                    tmpData += len;
                    remaining -= len;
                }

                // there is a "DisparityBox" after this according to the spec, but we ignore it
                break;
            }
            default:
            {
                break;
            }
        }

        data += chunkSize;
        size -= chunkSize;
    }

    return OK;
}

}  // namespace android
