diff options
Diffstat (limited to 'src/codec/img-codec-parser.c')
-rwxr-xr-x | src/codec/img-codec-parser.c | 505 |
1 files changed, 0 insertions, 505 deletions
diff --git a/src/codec/img-codec-parser.c b/src/codec/img-codec-parser.c deleted file mode 100755 index 182da69..0000000 --- a/src/codec/img-codec-parser.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * libmedia-thumbnail - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Hyunjun Ko <zzoon.ko@samsung.com> - * - * 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 <media-util-err.h> -#include "media-thumb-debug.h" -#include "img-codec-parser.h" - -static unsigned char gIfegPNGHeader[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; -static unsigned char gIfegJPEGHeader[] = { 0xFF, 0xD8 }; -static unsigned char gIfegGIFHeader[] = { "GIF" }; -static unsigned char gIfegBMPHeader[] = { 0x42, 0x4D }; -static unsigned char gIfegWBMPHeader[] = { 0x00, 0x00 }; - -void __ImgGetFileAttributes(const char *szPathName, unsigned long *pFileAttr) -{ - FILE *f = NULL; - - f = fopen(szPathName, "r"); - if (f != NULL) { - fseek(f, 0, SEEK_END); - *pFileAttr = ftell(f); - fclose(f); - } -} - -static int _CheckBuffer(IFEGSTREAMCTRL *pIfegstreamctrl, unsigned int size) -{ - unsigned long fileread; - - if ((size + pIfegstreamctrl->buffpos) > pIfegstreamctrl->buffend) { - if (pIfegstreamctrl->filepos == pIfegstreamctrl->filesize) - return MS_MEDIA_ERR_INTERNAL; - - if (pIfegstreamctrl->buffpos == 0) { - fileread = fread(pIfegstreamctrl->buffer, sizeof(char), FILE_READ_SIZE, pIfegstreamctrl->fd); - if (fileread == 0) - return MS_MEDIA_ERR_INTERNAL; - - pIfegstreamctrl->buffend = fileread; - pIfegstreamctrl->filepos += fileread; - pIfegstreamctrl->buffpos = 0; - } else { - - if (size >= 2048 || pIfegstreamctrl->buffend - pIfegstreamctrl->buffpos > FILE_READ_SIZE) - return MS_MEDIA_ERR_INTERNAL; - - memcpy(pIfegstreamctrl->buffer, &pIfegstreamctrl->buffer[pIfegstreamctrl->buffpos], pIfegstreamctrl->buffend - pIfegstreamctrl->buffpos); - fileread = fread(&pIfegstreamctrl->buffer[pIfegstreamctrl->buffend - pIfegstreamctrl->buffpos], sizeof(char), pIfegstreamctrl->buffpos, pIfegstreamctrl->fd); - if (fileread == 0) - return MS_MEDIA_ERR_INTERNAL; - - pIfegstreamctrl->buffend = pIfegstreamctrl->buffend - pIfegstreamctrl->buffpos + fileread; - pIfegstreamctrl->buffpos = 0; - pIfegstreamctrl->filepos += fileread; - } - return MS_MEDIA_ERR_NONE; - } - return MS_MEDIA_ERR_NONE; -} - -static unsigned int _IfegReadUINT(unsigned char *pBuffer) -{ - return (((*pBuffer) << 24) | ((*(pBuffer + 1)) << 16) | ((*(pBuffer + 2)) << 8) | (*(pBuffer + 3))); -} - -static int _ImgGetImageInfo(FILE *hFile, unsigned long fileSize, char *fileExt, ImgCodecType *type, unsigned int *width, unsigned int *height) -{ - unsigned int fileleft; - unsigned long fileread; - unsigned char EncodedDataBuffer[4096]; - - unsigned int *pWidth = NULL; - unsigned int *pHeight = NULL; - int ret = MS_MEDIA_ERR_NONE; - - if (type == NULL || width == NULL || height == NULL) { - return MS_MEDIA_ERR_INVALID_PARAMETER; - } else { - pWidth = width; - pHeight = height; - - *type = IMG_CODEC_UNKNOWN_TYPE; - *pWidth = 0; - *pHeight = 0; - } - - memset(EncodedDataBuffer, 0, 4096); - - fileread = fread(EncodedDataBuffer, sizeof(char), 8, hFile); - if (fileread < MINIMUM_HEADER_BYTES) { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE"); - return ret; - } - - if (memcmp(EncodedDataBuffer, gIfegJPEGHeader, JPG_HEADER_LENGTH) == 0) { - unsigned char header_type[JPG_HEADER_TYPE_LENGTH]; - unsigned char block_size[JPG_BLOCK_SIZE_LENGTH]; - unsigned char image_size[JPG_IMAGE_SIZE_LENGTH]; - - rewind(hFile); - - unsigned short block_length = EncodedDataBuffer[4] * 256 + EncodedDataBuffer[5]; - thumb_dbg("block length : %d", block_length); - unsigned int i = 4; - - if (fseek(hFile, block_length + 4, SEEK_CUR) < 0) { - thumb_err("fseek was failed"); - return MS_MEDIA_ERR_FILE_READ_FAIL; - } - - while (i < fileSize) { - i += block_length; - if (i >= fileSize) { - thumb_warn("Failed to get w / h from jpeg at index [%d]", i); - break; - } - - memset(header_type, 0, JPG_HEADER_TYPE_LENGTH); - fileread = fread(header_type, sizeof(char), JPG_HEADER_TYPE_LENGTH, hFile); - - if (header_type[0] != 0xFF) { - thumb_warn("Failed to get w / h from jpeg at index [%d]", i); - break; - } - - if (header_type[1] == 0xC0 || header_type[1] == 0xC2) { - memset(image_size, 0, JPG_IMAGE_SIZE_LENGTH); - fileread = fread(image_size, sizeof(char), JPG_IMAGE_SIZE_LENGTH, hFile); - - *pWidth = image_size[5] * 256 + image_size[6]; - *pHeight = image_size[3] * 256 + image_size[4]; - break; - } else { - i += 2; - memset(block_size, 0, JPG_BLOCK_SIZE_LENGTH); - fileread = fread(block_size, sizeof(char), JPG_BLOCK_SIZE_LENGTH, hFile); - block_length = block_size[0] * 256 + block_size[1]; - thumb_dbg("new block length : %d", block_length); - - if (fseek(hFile, block_length-JPG_BLOCK_SIZE_LENGTH, SEEK_CUR) < 0) { - thumb_err("fseek was failed"); - return MS_MEDIA_ERR_FILE_READ_FAIL; - } - } - } - thumb_dbg("IMG_CODEC_JPEG : W[%d] H[%d]", *pWidth, *pHeight); - *type = IMG_CODEC_JPEG; - } - /*********************** PNG *************************/ - else if (memcmp(EncodedDataBuffer, gIfegPNGHeader, PNG_HEADER_LENGTH) == 0) { - unsigned char tmp; - - fileread = fread(EncodedDataBuffer, sizeof(char), 32, hFile); - if (fileread < 32) { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE in PNG"); - return ret; - } - /* Get Image Width */ - if (pWidth) - *pWidth = _IfegReadUINT((EncodedDataBuffer + 8)); - - /* Get Image Height */ - if (pHeight) - *pHeight = _IfegReadUINT((EncodedDataBuffer + 12)); - - /* Read Interlace byte */ - tmp = *(EncodedDataBuffer + 20); - /* If image is interlaced then multiple should be 2 */ - if (tmp) { - thumb_dbg("Interlaced PNG Image."); - } - thumb_dbg("IMG_CODEC_PNG"); - *type = IMG_CODEC_PNG; - } - /*********************** BMP *************************/ - else if (memcmp(EncodedDataBuffer, gIfegBMPHeader, BMP_HEADER_LENGTH) == 0) { - /* Parse BMP File and get image width and image height */ - fileread = fread(&EncodedDataBuffer[8], sizeof(char), 18, hFile); - if (fileread < 18) { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE in BMP"); - return ret; - } - if (pWidth) { - *pWidth = - EncodedDataBuffer[18] | (EncodedDataBuffer[19] << 8) - | (EncodedDataBuffer[20] << 16) | - (EncodedDataBuffer[21] << 24); - } - if (pHeight) { - // add the reference function abs(). may have negative height values in bmp header. - *pHeight = abs(EncodedDataBuffer[22] | (EncodedDataBuffer[23] << 8) | (EncodedDataBuffer[24] << 16) | (EncodedDataBuffer[25] << 24)); - } - - thumb_dbg("IMG_CODEC_BMP"); - *type = IMG_CODEC_BMP; - } - /*********************** GIF *************************/ - else if (memcmp(EncodedDataBuffer, gIfegGIFHeader, GIF_HEADER_LENGTH) == 0) { - unsigned int tablelength = 0; - unsigned int imagecount = 0; - int finished = 0; - unsigned char temp; - unsigned int length; - IFEGSTREAMCTRL ifegstreamctrl; - - if (13 > fileSize) { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE in GIF"); - return ret; - } - - fileread = fread(&EncodedDataBuffer[8], sizeof(char), 5, hFile); - if (fileread < 5) { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE in GIF"); - return ret; - } - - if (EncodedDataBuffer[0] != 'G' || EncodedDataBuffer[1] != 'I' - || EncodedDataBuffer[2] != 'F' || EncodedDataBuffer[3] < '0' - || EncodedDataBuffer[3] > '9' || EncodedDataBuffer[4] < '0' - || EncodedDataBuffer[4] > '9' || EncodedDataBuffer[5] < 'A' - || EncodedDataBuffer[5] > 'z') { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE in GIF"); - return ret; - } - - *pWidth = EncodedDataBuffer[6] | (EncodedDataBuffer[7] << 8); - *pHeight = EncodedDataBuffer[8] | (EncodedDataBuffer[9] << 8); - - thumb_dbg("Logical width : %d, Height : %d", *pWidth, *pHeight); - - if ((EncodedDataBuffer[10] & 0x80) != 0) { /* Global color table */ - temp = (EncodedDataBuffer[10] & 0x7) + 1; - tablelength = (1 << temp) * 3; - - if ((tablelength * sizeof(char)) > sizeof(EncodedDataBuffer)) { - thumb_warn("_ImgGetInfoStreaming :table length is more than buffer length"); - return ret; - } - - if (13 + tablelength > fileSize) { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE in GIF"); - return ret; - } - /* coverity[ -tainted_data_argument : EncodedDataBuffer ] */ - fileread = fread(EncodedDataBuffer, sizeof(char), tablelength, hFile); - if (fileread < tablelength) { - thumb_warn("IMG_CODEC_UNKNOWN_TYPE in GIF"); - return ret; - } - } - - fileleft = fileSize - 13 - tablelength; - - ifegstreamctrl.fd = hFile; - ifegstreamctrl.filesize = fileleft; - ifegstreamctrl.filepos = 0; - ifegstreamctrl.buffpos = 0; - ifegstreamctrl.buffend = 0; - ifegstreamctrl.buffer = EncodedDataBuffer; - - while (!finished) { - if (ifegstreamctrl.buffpos > ifegstreamctrl.buffend) - break; - if (_CheckBuffer(&ifegstreamctrl, 1) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - switch (EncodedDataBuffer[ifegstreamctrl.buffpos++]) { - - case 0x3b: /* End of the GIF dataset */ - finished = 1; - break; - - case 0x21: /* Extension Block */ - if (_CheckBuffer(&ifegstreamctrl, 1) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - switch (EncodedDataBuffer[ifegstreamctrl.buffpos++]) { - - case 0xf9: /* Graphic control extension block */ - if (_CheckBuffer(&ifegstreamctrl, 6) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - if (4 != EncodedDataBuffer[ifegstreamctrl.buffpos++]) { /* data length : fixed 4 bytes */ - *type = 0; - } - ifegstreamctrl.buffpos += 4; - ifegstreamctrl.buffpos++; /* block end */ - break; - - case 0x01: /* Plain Text block */ - case 0xfe: /* Comment Extension block */ - case 0xff: /* Appliation Extension block */ - if (_CheckBuffer(&ifegstreamctrl, 1) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - if (ifegstreamctrl.buffpos > sizeof(EncodedDataBuffer)) { - thumb_warn("buffer position exceeds buffer max length "); - return ret; - } - - while ((ifegstreamctrl.buffpos < sizeof(EncodedDataBuffer)) - && ((length = EncodedDataBuffer[ifegstreamctrl.buffpos++]) > 0)) { /* get the data length */ - if (_CheckBuffer(&ifegstreamctrl, length) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - /* Check integer overflow */ - if (ifegstreamctrl.buffpos > 0xffffffff - length) { - thumb_err("Prevent integer overflow.."); - return ret; - } - - ifegstreamctrl.buffpos += (length); - /* File End Check */ - } - break; - - default: - break; - } - - break; - - case 0x2c: /* Start of an image object. Read the image description. */ - - if (_CheckBuffer(&ifegstreamctrl, 9) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } -#if 1 - if (imagecount == 0) { - /* Regard the width/height of the first image block as the size of thumbnails. */ - int img_block_w = 0, img_block_h = 0; - - img_block_w = EncodedDataBuffer[ifegstreamctrl.buffpos + 4] |(EncodedDataBuffer[ifegstreamctrl.buffpos + 5] << 8); - img_block_h = EncodedDataBuffer[ifegstreamctrl.buffpos + 6] |(EncodedDataBuffer[ifegstreamctrl.buffpos + 7] << 8); - thumb_dbg("Image block width : %d, Height : %d", img_block_w, img_block_h); - - *pWidth = img_block_w; - *pHeight = img_block_h; - } -#endif - /* Color Resolution */ - if ((EncodedDataBuffer[ifegstreamctrl.buffpos + 8] & 0x80) != 0) { /* Logical color table */ - temp = (EncodedDataBuffer[ifegstreamctrl.buffpos + 8] & 0x7) + 1; - length = (1 << temp) * 3; - if (_CheckBuffer(&ifegstreamctrl, length + 9) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - ifegstreamctrl.buffpos += length; - /* File End Check */ - } - - ifegstreamctrl.buffpos += 9; - - if (_CheckBuffer(&ifegstreamctrl, 1) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - temp = EncodedDataBuffer[ifegstreamctrl.buffpos++]; - if (temp < 2 || 9 < temp) { - return ret; - } - - do { - if (_CheckBuffer(&ifegstreamctrl, 1) != MS_MEDIA_ERR_NONE) { - thumb_warn("_CheckBuffer was failed"); - return ret; - } - - length = EncodedDataBuffer[ifegstreamctrl.buffpos++]; - if ((length + ifegstreamctrl.buffpos) > ifegstreamctrl.buffend) { - length = length + ifegstreamctrl.buffpos - ifegstreamctrl.buffend; - if (fseek(ifegstreamctrl.fd, length, SEEK_CUR) < 0) { - if (imagecount) { - thumb_dbg("IMG_CODEC_AGIF"); - *type = IMG_CODEC_AGIF; - return ret; - } - return MS_MEDIA_ERR_FILE_READ_FAIL; - } - ifegstreamctrl.filepos += length; - ifegstreamctrl.buffpos = 0; - ifegstreamctrl.buffend = 0; - } else { - ifegstreamctrl.buffpos += length; - } - - /* File End Check */ - } while (length); - if (!imagecount) - imagecount++; - else { - thumb_dbg("IMG_CODEC_AGIF"); - *type = IMG_CODEC_AGIF; - return ret; - } - break; - - default: - finished = 0; - break; - - } - } - thumb_dbg("IMG_CODEC_GIF"); - *type = IMG_CODEC_GIF; - } - /*********************** WBMP *************************/ - else if ((memcmp(EncodedDataBuffer, gIfegWBMPHeader, WBMP_HEADER_LENGTH) == 0) && (strcasecmp(fileExt, "wbmp") == 0)) { - /* Parse BMP File and get image width and image height */ - if (pWidth) - *pWidth = EncodedDataBuffer[2]; - - if (pHeight) - *pHeight = EncodedDataBuffer[3]; - - thumb_dbg("IMG_CODEC_WBMP W[%d] H[%d]", *pWidth, *pHeight); - *type = IMG_CODEC_WBMP; - } - return ret; -} - -static int _ImgGetFileExt(const char *file_path, char *file_ext, int max_len) -{ - int i = 0; - - for (i = (int)strlen(file_path); i >= 0; i--) { - if ((file_path[i] == '.') && (i < (int)strlen(file_path))) { - strncpy(file_ext, &file_path[i + 1], max_len); - return MS_MEDIA_ERR_NONE; - } - - /* meet the dir. no ext */ - if (file_path[i] == '/') - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - return MS_MEDIA_ERR_INVALID_PARAMETER; -} - -int ImgGetImageInfo(const char *filePath, ImgCodecType *type, unsigned int *width, unsigned int *height) -{ - FILE *hFile; - unsigned long file_size = 0; - char file_ext[10] = { 0, }; - int ret = 0; - - if (filePath == NULL) - return MS_MEDIA_ERR_INVALID_PARAMETER; - - hFile = fopen(filePath, "rb"); - if (hFile == NULL) { - thumb_err("file open error: %s", filePath); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - __ImgGetFileAttributes(filePath, &file_size); - if (file_size == 0) { - fclose(hFile); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - ret = _ImgGetFileExt(filePath, file_ext, sizeof(file_ext)); - if (ret != MS_MEDIA_ERR_NONE) { - thumb_warn("_media_thumb_get_file_ext failed"); - } - - ret = _ImgGetImageInfo(hFile, file_size, file_ext, type, width, height); - - fseek(hFile, 0, SEEK_SET); - fclose(hFile); - - return ret; -} |