Unwanted & strange artefacts in PVRTC textures

Greetings,





I’m having an issue with libPVRTexLib.a on Mac OS X.





To sum it up, PVRTC compressed textures seem to exhibit artifacts even in places there should clearly be no pixels at all (see pictures below).





Using the PVRTexTool on Windows doesn’t yield such results (but is not an option for our workflow).











Our workflow is as follows:





- We have a master PNG image (with transparency) for our texture of an arbitrary size.





- We load it into a buffer and append some padding at the right & bottom so that our texture buffer is now a square with a power-of-2 side. Padding is made of fully transparent black pixels (ie. 0x00000000).





- We compress it using the “CompressPVR” method of the “PVRTextureUtilities” class. Alpha is set to yes and the pixel type to OGL_PVRTC4.





- Now we can either load it in our engine and display it in the iPhone Simulator, or on the device itself.








For optimal visual feedback of the issue, I used the method “DecompressPVR” to create a PNG file holding the uncompressed PVRTC texture.








Here is the original PNG image (with padding):











Here is the uncompressed PVRTC image:











Notice the area circled in red, there is some content yet this should all be part of the transparent padding as the actual source image data is only 35 pixels wide. This problem is also visible where the actual rectangular source image was copied, its just a little harder to notice. This seems to be related to fully transparent pixels (or is just too hard to see on opaque patterns).





Anybody experiencing the same behavior? Or better yet, any fix/workaround for this issue?





Thank you for your time!

Nobody having a slight idea of what is going on?

I have looked at this issue and have been unable to reproduce it. I viewed the image in PVRTexTool.

Can you send the compressed .pvr file to devtech@imgtec.com? Which version of the SDK have you taken PVRTexLib from?



this is likely an artifact in that the compression algorithm may not


handle the appended image. Try resizing the image I use ImageMagick


tool. here’s my pipepline pvr maker for jpegs less than 9k dimensions(perl).














   # use ImageMagick’s convert (resize to square power of 2, max 2046 resolution)


   # and ImgTech’s PVRTexTool to make a pvr file using format pvrtc4


   # and the Storable persistent perl to key the size/filename/type to a file location


   # to probably avoid conversions already done.


   #


   #


   # creates square power of 2 sized png (resizing if required )in pvrDir


   #        and pvrtc4 formated conversion of this in pvrDir


   #


   # maximum of size of 9128, otherwise image will be distorted too much, and too large


   # for general texture onto mobile computers


   #


sub generateCachedPVR($;$$) {


   my ($still, $cacheStorePath, $pvrDir) = @_;





   my ($imageFile, $baseUserDir, $pvrTexTool, $convertTool, $fileInfo,


       $imageFileType, $dim_x, $dim_y, $size, $resize, $resize2, $i, $prevI, $imageFileType,


       $isSquare, $pwr2Diff, $pwr2, $png, $pvr, $entry, $indexHash, $fileName,


       $maxSize, @pwr2s, );   





   


   $baseUserDir = File::HomeDir->my_home."/cgpworld/file_fiddle/";


   if(not -d $baseUserDir) { confess “$baseUserDir is not an existing directory.n”;}





   if( isStill($still) ) {


      $imageFile = getStillFilenameKey($still);


   }


   else {


      $imageFile = $still;


   }





   if( not -f $imageFile) {


      confess “file: $imageFile does not exist.n”;


   }


   else {


      if( -d $imageFile) {confess “imageFile is a directory.n”; }


      if( -l $imageFile) {confess “imageFile is a link.n”; }


   }


      #


      # $fileName = getFileBaseName($imageFile); # includes extension


      #


   if( $imageFile =~ /.+/(.+)./) { # please only one ‘.’ in the path


      $fileName = $1;


   }


   elsif( $imageFile =~ /^(.+)./) { # no path


      $fileName = $1;


   }


   else {


      confess “failed to get the filename before the file extent in $imageFilen”;


   }





   if( not defined $pvrDir) {


      $pvrDir = $baseUserDir.“pvrFiles/”;


      if( not -d $pvrDir) {


        mkdir($pvrDir, 0777) || confess “Attempting to make directory $pvrDir failed.n”;


      }


   }


   else {


      if(not -d $pvrDir) { confess " $pvrDir is not a directory.n"; }


   }


   if( not defined $cacheStorePath) {


      $cacheStorePath = $pvrDir.“pvrFileIndex.stor”;


   }


   $pvrTexTool = File::HomeDir->my_home."/cgpworld/file_fiddle/PVRTexTool";


   $convertTool = ‘convert’; # main imageMagick interface





   $fileInfo = identify '$imageFile';   # part of imageMagick suite


   # print “fileinfo: $fileInfon”;


   if( $fileInfo =~ /([A-Z]+)s(d+)x(d+)/) {


       $imageFileType = $1;


       $dim_x = $2;


       $dim_y = $3;


       # print “file:$imageFile, type:$imageFileType dim_x:$dim_x dim_y:$dim_y n”;


   }


   else {


      confess “failed fileInfo string format.n”;


   }





   @pwr2s = (16, 32, 64, 128, 256, 516, 1032, 2064);





   $maxSize = 9128;





   if( $dim_x > $maxSize or


       $dim_y > $maxSize) {


      confess “file $imageFile too large ($dim_x, $dim_y) for resizing for pvrtc4 compressed format.n”.


              “The shrinking to 2064 will distort too much.n”;


   }


   $isSquare = ($dim_x == $dim_y)? 1: 0;


   if( $isSquare ) {


      $pwr2 = 0;


      foreach $i (@pwr2s) {


      if( $dim_x == $i) {


         $pwr2 = 1;


            last;


      }


      }


   }


   else {


      $pwr2 = 0;


   }





   $png = $pvrDir.$fileName.".png";


   $pvr = $pvrDir.$fileName.".pvr";





     # resize to square power of 2, max 2064 resolution


   if( not $pwr2) {


      $size = $dim_x > $dim_y? $dim_x: $dim_y;


          # resize down to pw2 sq unless <= 16


      foreach $i (@pwr2s) {


      if( $size <= 16 ) {


         $resize = 16;


            last;


        }


        elsif( $size >= 2064) {             


         $resize = 2064;


            last;


        }    


        elsif( $size >= 0.8 * 2 * $i ) {


         $resize = 2 *$i;


        }


        elsif($size >= $i) {


            $resize = $i;


        }


                 


        $prevI = $i;


      }


      $resize2 = “-resize $resize”.“x$resize!”;   # ! required to force the actual resize, not the max dimension fit


   }


   else {


      $resize = $dim_x;


   }


   if( not inIndexedFileStore($cacheStorePath, $imageFile, $imageFileType, $resize)) {


      if( not $pwr2) {


        $convertTool $resize2 '$imageFile' '$png';


      }


      else {


        $convertTool '$imageFile' '$png';


      }


      





      $pvrTexTool -fpvrtc4 -i$png -o$pvr;


      wait;


      $size = -s $pvr; # this is less than what finder displays, but is indicative


      print “pvr file $fileName.pvr created approx size ($size bytes?) resized ($resize sq) original ($dim_x, $dim_y)n”;


   }


   


}


Having got the stuff onto an ipad , a correction


replace $pvrTexTool -fpvrtc4 -i$png -o$pvr;


with     $pvrTexTool -fOGLPVRTC4 -i$png -o$pvr;


   PVRTTextureAPI.cpp don’t like pvrtc4.