| /** |
| * Copyright (C) 2020 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. |
| */ |
| #define _GNU_SOURCE |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include "openjpeg.h" |
| #include "opj_includes.h" |
| |
| #define REPEATVALUES 100000 |
| |
| unsigned char gStartValues[] = { 0xFF, 0x4F, 0xFF, 0x51, 0x00, 0x2F, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x2E, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x01, |
| 0x01, 0x07, 0x01, 0x01, 0x07, 0x01, 0x01, 0xFF, 0x64, 0x00, 0x23, 0x00, |
| 0x01, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6F, 0x72, 0x3A, 0x20, 0x4A, 0x61, |
| 0x73, 0x50, 0x65, 0x72, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, |
| 0x20, 0x31, 0x2E, 0x37, 0x30, 0x30, 0x2E, 0x31, 0xFF, 0x52, 0x00, 0x0C, |
| 0x00, 0x00, 0x00, 0x01, 0x01, 0x05, 0x04, 0x04, 0x00, 0x01, 0xFF, 0x5C, |
| 0x00, 0x13, 0x40, 0x40, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, |
| 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0xFF, 0x5D, 0x00, 0x14, 0x01, |
| 0x40, 0x40, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48, |
| 0x48, 0x50, 0x48, 0x48, 0x50, 0xFF, 0x5D, 0x00, 0x14, 0x02, 0x40, 0x40, |
| 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, |
| 0x48, 0x48, 0x50 }; |
| unsigned int gNumStartValues = sizeof(gStartValues) / sizeof(gStartValues[0]); |
| |
| unsigned char gRepeatValues[] = { 0xFF, 0x75, 0x00, 0x09, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00 }; |
| unsigned int gNumRepeatValues = sizeof(gRepeatValues) |
| / sizeof(gRepeatValues[0]); |
| |
| unsigned char gLastValues[] = { 0xFF, 0x75, 0x00, 0x09, 0x00, 0x00, 0x01, 0x00, |
| 0x00, 0x00, 0x00 }; |
| unsigned int gNumLastValues = sizeof(gLastValues) / sizeof(gLastValues[0]); |
| |
| typedef struct { |
| char* blob; |
| ssize_t blobSize; |
| ssize_t readPos; |
| } applicationContext; |
| |
| static OPJ_SIZE_T ReadHandler(void *buffer, OPJ_SIZE_T length, void *context) { |
| applicationContext* appContext = (applicationContext*) context; |
| ssize_t count = 0; |
| ssize_t rem = 0; |
| if (!appContext) { |
| return ((OPJ_SIZE_T) - 1); |
| } |
| rem = appContext->blobSize - appContext->readPos; |
| if ((ssize_t) length <= rem) { |
| count = length; |
| } else { |
| count = rem; |
| } |
| memcpy(buffer, &appContext->blob[appContext->readPos], count); |
| appContext->readPos += count; |
| return ((OPJ_SIZE_T) length); |
| } |
| |
| int main(void) { |
| ssize_t offset = 0; |
| unsigned int count = 0; |
| applicationContext sContext; |
| opj_j2k_t* codec = NULL; |
| opj_stream_t* stream = NULL; |
| opj_image_t* image = NULL; |
| opj_stream_private_t* private = NULL; |
| opj_event_mgr_t eventMgr; |
| stream = opj_stream_default_create(OPJ_TRUE); |
| private = (opj_stream_private_t*)stream; |
| |
| sContext.blobSize = gNumStartValues + REPEATVALUES * gNumRepeatValues |
| + gNumLastValues; |
| sContext.blob = (char*) opj_malloc(sContext.blobSize); |
| if (!sContext.blob) { |
| return EXIT_FAILURE; |
| } |
| memset(sContext.blob, 0, sContext.blobSize); |
| |
| memcpy(&sContext.blob[offset], gStartValues, gNumStartValues); |
| offset += gNumStartValues; |
| for (count = 0; count < REPEATVALUES; count++) { |
| memcpy(&sContext.blob[offset], gRepeatValues, gNumRepeatValues); |
| offset += gNumRepeatValues; |
| } |
| memcpy(&sContext.blob[offset], gLastValues, gNumLastValues); |
| offset += gNumLastValues; |
| sContext.readPos = 0; |
| private->m_read_fn = ReadHandler; |
| private->m_user_data = (void*)&sContext; |
| private->m_user_data_length = sContext.blobSize; |
| private->m_free_user_data_fn = NULL; |
| codec = opj_j2k_create_decompress(); |
| opj_set_default_event_handler(&eventMgr); |
| opj_j2k_read_header(private,codec,&image,&eventMgr); |
| opj_free(sContext.blob); |
| return EXIT_SUCCESS; |
| } |