OSDN Git Service

RLE圧縮されたTGAファイルも読み込めるように修正.
authorrezoo <rezoolab@gmail.com>
Wed, 21 Oct 2009 16:34:06 +0000 (01:34 +0900)
committerrezoo <rezoolab@gmail.com>
Wed, 21 Oct 2009 16:34:06 +0000 (01:34 +0900)
src/cpp/pdutility.cpp
src/test/load_tga.cpp
src/test/logo.tga
src/test/logo_RLE.tga [new file with mode: 0644]

index 553bb18..4791f71 100644 (file)
@@ -28,18 +28,27 @@ IplImage* pd::loadTGAImage(const char* filename) {
   FILE* fp = fopen(filename, "rb");
   
   unsigned char tgaheader[18];
-  if(fread(tgaheader, 1, 18, fp) != 18) return NULL;
+  if(fread(tgaheader, 1, 18, fp) != 18){
+    fclose(fp);
+    return NULL;
+  }
   
   format = tgaheader[2];
   width = *(short*)(tgaheader + 12);
   height = *(short*)(tgaheader + 14);
   depth_color = tgaheader[16];
+  unsigned char channel = depth_color/8;
   
-  unsigned int imgsize = depth_color/8*width*height;
+  unsigned int imgsize = channel*width*height;
   imageData = new char[imgsize];
   
   if(format == TGA_TYPE_FULLCOLOR) {
-    if(fread(imageData, 1, imgsize, fp) != imgsize) return NULL;
+    // \83t\83\8b\83J\83\89\81[\89æ\91\9c(RLE\88³\8fk\82È\82µ)\82Ì\8fê\8d\87
+    if(fread(imageData, 1, imgsize, fp) != imgsize){
+      delete [] imageData;
+      fclose(fp);
+      return NULL;
+       }
     
     if(depth_color == TGA_DEPTH_24BIT){
       img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 3);
@@ -47,19 +56,63 @@ IplImage* pd::loadTGAImage(const char* filename) {
     }else if(depth_color == TGA_DEPTH_32BIT){
       img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 4);
       img->imageData = imageData;
-    }else return NULL;
-    
+    }else{
+      delete [] imageData;
+      fclose(fp);
+      return NULL;
+    }
   } else if(format == TGA_TYPE_FULLCOLOR_RLE) {
-    /*
-    unsigned char chunkheader = 0;
-    
-    if(fread(&chunkheader, sizeof(unsigned char), 1, fp) == 0){
+    // \83t\83\8b\83J\83\89\81[\89æ\91\9c(RLE\88³\8fk\82 \82è)\82Ì\8fê\8d\87
+    if((depth_color != TGA_DEPTH_32BIT) &&
+       (depth_color != TGA_DEPTH_24BIT)){
       fclose(fp);
       delete [] imageData;
       return NULL;
     }
-    */
-    // TODO:\82Æ\82è\82 \82¦\82¸\96¢\88³\8fk\82Ì\82â\82Â\82à\82â\82Á\82Ä\82¨\82­
+    
+    unsigned int i=0;
+    unsigned char first_byte;
+    while(i<imgsize){
+      if(fread(&first_byte, 1, 1, fp) != 1){
+        delete [] imageData;
+        fclose(fp);
+        return NULL;
+      }
+      
+      // \98A\91±\83f\81[\83^\82©\82»\82¤\82Å\82È\82¢\82©\8c\9f\8fØ
+      if((first_byte >> 7) == 1){
+        // \98A\91±\82·\82é\83f\81[\83^\82Æ\82µ\82Ä\8f\88\97\9d
+        unsigned char num = (first_byte & 127) + 1;
+        
+        char b[4];
+        if(fread(b, 1, channel, fp) != channel){
+          delete [] imageData;
+          fclose(fp);
+          return NULL;
+        }
+        for(int j=0; j<num; j++){
+          for(int k=0; k<channel; k++) imageData[i+j*channel+k] = b[k];
+        }
+        i += num*channel;
+      }else{
+        // \98A\91±\82µ\82È\82¢\83f\81[\83^\82Æ\82µ\82Ä\8f\88\97\9d
+        unsigned char num = first_byte + 1;
+        unsigned int read_byte = num*channel;
+        if(fread((imageData + i), 1, read_byte, fp) != read_byte){
+          delete [] imageData;
+          fclose(fp);
+          return NULL;
+        }
+        i += read_byte;
+      }
+    }
+    
+    if(depth_color == TGA_DEPTH_24BIT)
+      img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 3);
+    else if(depth_color == TGA_DEPTH_32BIT)
+      img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 4);
+    img->imageData = imageData;
+    
   } else {
     fclose(fp);
     return NULL;
index f476699..27bf0f1 100644 (file)
 \r
 using namespace std;\r
 \r
-void usage(){\r
-  cout << "load_tga" << endl;\r
-}\r
-\r
 int main(int argc, char* argv[]) {\r
-  IplImage *src;\r
-\r
-  if(argc != 2 || (src = pd::loadTGAImage(argv[1])) == NULL){\r
-    usage();\r
-    return -1;\r
+  IplImage* src1 = pd::loadTGAImage("logo.tga");
+  IplImage* src2 = pd::loadTGAImage("logo_RLE.tga");
+  
+  if((src1 == NULL)||(src2 == NULL)){
+    cout << "error." << endl;
+    cout << "please check out the compile option." << endl;
   }\r
   \r
-  cvNamedWindow("tgaimage", CV_WINDOW_AUTOSIZE);\r
-  cvShowImage("tgaimage", src);\r
+  cvNamedWindow("TGAimage(Uncompressed)", CV_WINDOW_AUTOSIZE);
+  cvNamedWindow("TGAimage(Compressed)", CV_WINDOW_AUTOSIZE);\r
+  cvShowImage("TGAimage(Uncompressed)", src1);
+  cvShowImage("TGAimage(Compressed)", src2);
+  \r
   cvWaitKey(0);\r
   \r
-  cvDestroyWindow("tgaimage");\r
-  cvReleaseImage(&src);\r
+  cvDestroyWindow("TGAimage(Uncompressed)");
+  cvDestroyWindow("TGAimage(Compressed)");\r
+  cvReleaseImage(&src1);
+  cvReleaseImage(&src2);\r
   \r
   return 0;\r
 }
index 5923d38..df6223b 100644 (file)
Binary files a/src/test/logo.tga and b/src/test/logo.tga differ
diff --git a/src/test/logo_RLE.tga b/src/test/logo_RLE.tga
new file mode 100644 (file)
index 0000000..7d18e0d
Binary files /dev/null and b/src/test/logo_RLE.tga differ