1. public class PVRTDecompress
  2. {
  3. /*
  4. author:FormatFa
  5. mail :1758759399@qq.com
  6. date :2017-6-14
  7. */
  8.  
  9. //modify from PVRTDecompress.cpp in PowerVR
  10. //https://github.com/gildor2/UModel libs dir
  11.  
  12. public static int Version3 = 0x03525650;
  13.  
  14. static int ETC_FLIP = 0x01000000;
  15. static int ETC_DIFF = 0x02000000;
  16.  
  17. static int[][] mod= new int[][]{
  18. {2, 8, -2, -8},
  19. {5, 17, -5, -17},
  20. {9, 29, -9, -29},
  21. {13, 42, -13, -42},
  22. {18, 60, -18, -60},
  23. {24, 80, -24, -80},
  24. {33, 106, -33, -106},
  25. {47, 183, -47, -183}
  26. };
  27.  
  28. /*
  29. PvrtHeader info from PVR File Format Specification.pdf
  30.  
  31. */
  32. public static int flag_NoFlag=0x0;
  33. //When this flag is set, colour values within the texture have been pre- multiplied by the alpha values
  34.  
  35. public static int flag_premultiplied=0x02;
  36.  
  37. //Texture data is in the Linear RGB colour space
  38. public static int colorSpace_LinearRGB=0;
  39. //Texture data is in the Standard RGB colour space
  40. public static int colorSpace_aRGB=1;
  41. public static int channel_UnsignedByteNormalised=0;
  42.  
  43. public static long format_ETC2_RGB=0x00000016;
  44.  
  45. public static class PVRTHeader
  46. {
  47. public int version;
  48. public int flags;
  49. public long pixelFormat;
  50. //int piexlFormat2;
  51. public int colorSpace;
  52. public int channelType;
  53. public int width;
  54. public int heigth;
  55. public int depth;
  56. public int numSurface;
  57. public int numFace;
  58. public int minMapCount;
  59. public int metaDataSize;
  60.  
  61. public byte[] imgdata;
  62.  
  63. @Override
  64. public String toString()
  65. {
  66.  
  67. return "version:"+Integer.toHexString(version)
  68. +"\nflag:"+Integer.toHexString(flags)
  69. +"\npiex:"+Long.toHexString(pixelFormat)
  70. +"\ncolor:"+Integer.toHexString(colorSpace)
  71. +"\nchannal:"+Integer.toHexString(channelType)
  72. +"\nwdth:"+Integer.toHexString(width)
  73. +"\nheigth:"+Integer.toHexString(heigth)
  74. +"\nsurface:"+Integer.toHexString(numSurface)
  75. +"\nface:"+Integer.toHexString(numFace)
  76. +"\nminp:"+Integer.toHexString(minMapCount)
  77. +"\nmeta:"+Integer.toHexString(metaDataSize);
  78.  
  79. }
  80.  
  81. }
  82.  
  83. void pri(int l)
  84. {
  85.  
  86. }
  87.  
  88. public static PVRTHeader loadPVRHeader(InputStream is) throws Exception
  89. {
  90.  
  91. PVRTHeader head = new PVRTHeader();
  92.  
  93. //if(head.version!=Version3)
  94. // throw new Exception("magic except:"+Integer.toHexString(head.version);
  95.  
  96. MyDataInputStream my = new MyDataInputStream(is);
  97.  
  98. head.version = my.readInt();
  99.  
  100. head.flags = my.readInt();
  101.  
  102. head.pixelFormat = my.readLong();
  103.  
  104. head.colorSpace = my.readInt();
  105.  
  106. head.channelType = my.readInt();
  107. head.width = my.readInt();
  108. head.heigth= my.readInt();
  109. head.depth = my.readInt();
  110. head.numSurface = my.readInt();
  111. head.numFace = my.readInt();
  112. head.minMapCount = my.readInt();
  113. head.metaDataSize = my.readInt();
  114.  
  115. is.skip(head.metaDataSize);
  116. byte[] data = new byte[my.available()];
  117. my.readFully(data);
  118.  
  119. head.imgdata = data;
  120. return head;
  121.  
  122. }
  123.  
  124. public static int[] PVRTDecompressETC_int(PVRTHeader head)
  125. {
  126.  
  127. List<Integer> t=new ArrayList<Integer>();
  128.  
  129. int[] piex=new int[head.width*head.heigth];
  130.  
  131. long blockTop,blockBot;
  132. long modtable1,modtable2;
  133.  
  134. boolean bFlip,bDiff;
  135.  
  136. char red1,green1,blue1;
  137. char red2,green2,blue2;
  138.  
  139. int offset=0;
  140. int mark = 0;
  141.  
  142. int w = head.width;
  143. int h = head.heigth;
  144.  
  145. byte[] data = head.imgdata;
  146.  
  147. for(int i = 0 ; i < h;i+=4)
  148. {
  149.  
  150. for(int j = 0; j<w;j+=4)
  151. {
  152.  
  153. int p = offset;
  154. mark = i*w+j;
  155.  
  156. blockTop = ByteUtils.byte2intLow(new byte[]{data[p],data[p+1],data[p+2],data[p+3]});
  157. blockBot = ByteUtils.byte2intLow(new byte[]{data[p+4],data[p+5],data[p+6],data[p+7]});
  158. // System.out.println(Integer.toHexString((int)blockTop)+" "+Integer.toHexString((int)blockBot));
  159.  
  160. offset+=8;
  161.  
  162. bFlip = ((blockTop&ETC_FLIP)!=0);
  163. bDiff = (blockTop&ETC_DIFF)!=0;
  164.  
  165. if(bDiff)
  166. {
  167.  
  168. blue1 =(char) ((blockTop & 0xf80000) >> 16);
  169. green1 = (char)((blockTop & 0xf800) >> 8);
  170. red1 = (char)(blockTop & 0xf8);
  171. // System.out.println("greeqn:"+(int)green1+",:"+(int)blue1+","+(int)red1);
  172.  
  173. //in c is signed char,
  174. // get differential colour for subblock 2
  175. char blues = (char)((blue1 >> 3) +(char) (((blockTop & 0x70000) >> 11) >> 5));
  176. char greens=( (char)( (green1 >> 3 )+ ( ((blockTop & 0x700) >> 3) >> 5)));
  177.  
  178. char reds =(char)( (red1 >> 3) + ( ((blockTop & 0x7) << 5) >> 5));
  179. // System.out.println("b:"+blockTop+ "sgreeqn:"+(int)greens+",:"+(int)blues+","+(int)reds);
  180.  
  181. blue2 = blues;
  182. green2 = greens;
  183. red2 = reds;
  184. if(offset<120&&bFlip)
  185. //
  186. System.out.println( (int)red1+"trs:"+(int)reds+"-- "+blockTop+ "_yes:"+ (int)red2+","+(int)green2+","+(int) blue2);
  187. //
  188. red1 =(char)( red1 + (red1 >> 5)); // copy bits to lower sig
  189. green1 = (char)( green1 + (green1 >> 5)); // copy bits to lower sig
  190. blue1 = (char)( blue1 + (blue1 >> 5)); // copy bits to lower sig
  191.  
  192. red2 = (char)( (red2 << 3) + (red2 >> 2)); // copy bits to lower sig
  193. green2 = (char)( (green2 << 3) + (green2 >> 2)); // copy bits to lower sig
  194. blue2 = (char)( (blue2 << 3) + (blue2 >> 2)); // copy bits to lower sig
  195.  
  196. }
  197. else
  198. {
  199. //System.out.println("diff");
  200. // individual mode 4 + 4 colour bits
  201. // get base colour for subblock 1
  202. blue1 =(char) ((blockTop & 0xf00000) >> 16);
  203. blue1 =(char) ( blue1 + (blue1 >> 4)); // copy bits to lower sig
  204. green1 =(char) (int)((blockTop & 0xf000) >> 8);
  205. green1 =(char) ( green1 + (green1 >> 4)); // copy bits to lower sig
  206. red1 = (char) (int)(blockTop & 0xf0);
  207. red1 =(char) (red1 + (red1 >> 4)); // copy bits to lower sig
  208.  
  209. // get base colour for subblock 2
  210. blue2 =(char) (int)((blockTop & 0xf0000) >> 12);
  211. blue2 = (char)( blue2 + (blue2 >> 4)); // copy bits to lower sig
  212. green2 =(char) (int)((blockTop & 0xf00) >> 4);
  213. green2 = (char)(green2 + (green2 >> 4)); // copy bits to lower sig
  214. red2 =(char)(int) ((blockTop & 0xf) << 4);
  215. red2 = (char)(red2 + (red2 >> 4)); // copy bits to lower sig
  216. // System.out.println("b:"+blockTop+"greeqn:"+(int)green2+",:"+(int)blue2+","+(int)red2);
  217.  
  218. }
  219.  
  220. // get the modtables for each subblock
  221. modtable1 = (blockTop >> 29) & 0x7;
  222. modtable2 = (blockTop >> 26) & 0x7;
  223.  
  224. if(!bFlip)/* 2*4 block */
  225. {
  226.  
  227. for (int a = 0; a< 4; a++) // vertical
  228. {
  229. for (int b = 0; b < 2; b++) // horizontal
  230. {
  231. //*(output + j * x + k) =
  232.  
  233. //
  234. piex[mark+ a*w+b]=(modifyPixel((int)red1, (int)green1, (int)blue1, b, a, blockBot, (int)modtable1));
  235. //*(output + j * x + k + 2) =
  236.  
  237. piex[ mark+ a*w+b+2]=
  238. // piex[mark+ a*w+b];
  239. (modifyPixel((int)red2, (int)green2,(int) blue2, b + 2, a, blockBot, (int)modtable2));
  240.  
  241. //if(offset<120)
  242. // System.out.println("no:"+piex[ mark+ a*w+b+2]);
  243.  
  244. }
  245. }
  246.  
  247. }
  248. else/*flip*/
  249. {
  250.  
  251. for (int a = 0; a< 2; a++) // vertical
  252. {
  253. for (int b = 0; b < 4; b++) // horizontal
  254. {
  255.  
  256. //*(output + j * x + k) =
  257. piex[ mark+ a*w+b]=(modifyPixel((int)red1, (int)green1, (int)blue1, b, a, blockBot, (int)modtable1));
  258.  
  259. //*(output + j * x + k + 2) =
  260. piex[ mark+ (a+2)*w+b]=
  261. // piex[ mark+ a*w+b];
  262. (modifyPixel((int)red2, (int)green2,(int) blue2, b ,a+2, blockBot, (int)modtable2));
  263. //
  264. if(offset<120)
  265. //
  266. System.out.println( bDiff+ "_yes:"+ (int)red2+","+(int)green2+","+(int) blue2+","+b+" ,"+(a+2) +":->"+piex[ mark+ (a+2)*w+b]);
  267. //
  268. }
  269. }
  270. }
  271.  
  272. }
  273.  
  274. }
  275.  
  276. return piex;
  277.  
  278. }
  279. /*
  280.  
  281. Decompress to ARGB8888
  282.  
  283. */
  284. public static byte[] PVRTDecompressETC(PVRTHeader head) throws IOException
  285. {
  286.  
  287. int[] pix = PVRTDecompressETC_int(head);
  288.  
  289. ByteArrayOutputStream os = new ByteArrayOutputStream();
  290.  
  291. MyDataOutPutStream myos = new MyDataOutPutStream(os);
  292. for(int p :pix)
  293. myos.writeInt(p);
  294. return ((ByteArrayOutputStream) myos.getOuputStream()).toByteArray();
  295.  
  296. }
  297.  
  298. /* !***********************************************************************
  299. @Function modifyPixel
  300. @Input red Red value of pixel
  301. @Input green Green
  302. value of pixel
  303. @Input blue Blue value of pixel
  304. @Input x Pixel x position
  305. in block @Input y Pixel y position in block
  306. @Input modBlock Values for the
  307. current block
  308. @Input modTable Modulation value
  309. s @Returns Returns actual
  310. pixel colour
  311. @Description Used by ETCTextureDecompress
  312. ************************************************************************ */
  313. static int modifyPixel(int red, int green, int blue, int x, int y,
  314. long modBlock, int modTable) {
  315. int index = x * 4 + y, pixelMod;
  316. long mostSig = modBlock << 1;
  317.  
  318. if (index < 8)
  319. pixelMod =
  320. mod[modTable][(int)(((modBlock >> (index + 24)) & 0x1) +
  321. ((mostSig >> (index + 8)) & 0x2))];
  322. else
  323. pixelMod =
  324. mod[modTable][(int)(((modBlock >> (index + 8)) & 0x1) +
  325. ((mostSig >> (index - 8)) & 0x2))];
  326.  
  327. red = _CLAMP_(red + pixelMod, 0, 255);
  328. green = _CLAMP_(green + pixelMod, 0, 255);
  329. blue = _CLAMP_(blue + pixelMod, 0, 255);
  330.  
  331. return ((red << 16) + (green << 8) + blue) | 0xff000000;
  332. }
  333.  
  334. private static int _CLAMP_(int pixelMod, int p1, int p2)
  335. {
  336. return (pixelMod)<(p2)? ((pixelMod)<(p1)?(p1):(pixelMod) ) : (p2);
  337. }
  338.  
  339. }

从PowerSDK里修改成的java版,结合安卓的类可以显示pvr图片

  1. int[] data=PVRTDecompress.PVRTDecompressETC_int(he);
  2. Bitmap bmp= Bitmap.createBitmap(data, he.width,he.heigth,Bitmap.Config.ARGB_8888);
  3. bmp.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(outname_png));

安卓版的pvr图片查看的更多相关文章

  1. 微信5.4安卓版重回ios风格 导航菜单都放底栏位置

    微信5.4安卓版发布更新了,由于本人的手机设置软件自动更新,中午的时候才发现微信换成了5.4版本,启动微信后是一个大大的“转账,就是发消息”,进入微信界面有点小惊喜,导航菜单都改为底部tab方式,顶部 ...

  2. 浩瀚技术 安卓版移动开单手持微POS PDA无线移动开单软件 -安卓版移动手持开单设备

    PDA数据采集器,是深圳浩瀚技术有限公司最新研发的一款安卓版移动手持开单设备,它通过WIFI和GPRS连接并访问电脑,从进销存软件中读取数据,实现移动开单,打破电脑开单模式. 它自带扫描器,可直接扫描 ...

  3. 中国首个 SaaS 模式的云告警平台安卓版 APP 上线

    今年一月底,国内首个 SaaS 模式的云告警平台 OneAlert 正式发布了 iOS 版 App 客户端,今天上午,安卓版 App 客户端也正式上线了!每个安卓用户,无需电脑,都可以通过手机全程跟踪 ...

  4. SQLSERVER图片查看工具SQL Image Viewer5.5.0.156

    原文:SQLSERVER图片查看工具SQL Image Viewer5.5.0.156 SQLSERVER图片查看工具SQL Image Viewer5.5.0.156 在2013年某一次北京SQL ...

  5. 2017年05月10日记一次微项目投产 | 安卓版微信内置浏览器不能解析gzip压缩过的mp4视频的问题

    前言 今天投产了一个小项目,一个很简单的H5,有播放视频功能,使用了videojs插件. 之前也做过数个视频播放,视频的转压都按照既定流程进行,文件放到FTP后,iphone和安卓机测试下来都没有问题 ...

  6. 一款基于 Android 开发的离线版的 MM 图片浏览 App

    一款离线版的 MM 图片浏览 App,有点类似掌上百度的图片专栏应用.图片采用瀑布流展示方式,点击图片集,支持左右手势滑动切换图片:支持放大缩小功能. 实现功能:1)图片完全离线,不耗个人 GPRS ...

  7. Win10默认图片查看器更改

    Win10自带的图片查看器不是很习惯,其背景乌漆嘛黑,宽扁的额头让人想起了黑边火腿肠手机,无法直视.怀念Win7和Win8.1的图片查看器,一个鼠标滚轮缩放自如的酸爽感觉.但却遗憾地发现,并不能直观地 ...

  8. 基于JQUERY 的图片查看插件

    viewer是一款功能强大的图片查看器.它可以实现ACDsee等看图软件的部分功能.它可以对图片进行移动,缩放,旋转,翻转,可以前后浏览一组图片.该图片查看器还支持移动设备,支持键盘控制,功能十分强大 ...

  9. 强大的jQuery图片查看器插件Viewer.js

    简介 Viewer.js 是一款强大的图片查看器 Viewer.js 有以下特点: 支持移动设备触摸事件 支持响应式 支持放大/缩小 支持旋转(类似微博的图片旋转) 支持水平/垂直翻转 支持图片移动 ...

随机推荐

  1. Python3.7和数据库MySQL 8.0.12 绿色解压 安装教程(一)

    首先要安装MySQL 数据库才可以继续安装图形工具SQLyog 第一步:下载解压包>> MYSQL官网地址:https://dev.mysql.com/downloads/file/?id ...

  2. s21day16 python笔记

    s21day16 python笔记 一.模块 1.1 模块的定义 模块的定义 可以吧一个py文件或一个文件夹(包)当作一个模块,以便于以后其他py文件的调用 包的定义(python2与python3的 ...

  3. java基础(二):java内部类

    内部类像寄生虫一样生存在其他类[外部类]的内部.定义在类的内部的类叫内部类,它缩小了可见性.根据内部类定义结构的不同,可以把内部类分为 成员内部类和局部内部类.成员内部类定义的地方和外部类的成员变量和 ...

  4. LVS详细介绍以及遇到的坑

    LVS详细介绍以及遇到的坑 一,概述 本文介绍了我搭建LVS集群的步骤,并且在使用LVS(Linux Virtual Server)过程中遇到的问题和坑, 二,LVS简单介绍 大家都知道,LVS中文意 ...

  5. Python assert(断言)

    Python assert(断言)可以分别后面的判断是否正确,如果错误会报错 示例: a = 1 assert type(a) is int print('No problem') 输出结果: No ...

  6. day059-60 ajax初识 登录认证练习 form装饰器, form和ajax上传文件 contentType

    一.ajax 的特点 1.异步交互:客户端发出一个请求后,需要等待服务器响应结束后, 才能发出第二个请求 2.局部刷新:给用户的感受是在不知不觉中完成请求和响应过程. 二.ajax 模板示例 ($.a ...

  7. 我提出了一个 Lean Html 5 的 概念 和 标准

    提出 Lean Html 5 是因为 Html 可以作为 一个 应用程序 开发 的 标准 和 平台, 应用程序 包括 Web 程序 , 本地程序 , 桌面程序 , 嵌入式程序 , 串口通信 等 . L ...

  8. 1.1.26 word内容导入PPT

    1.在开始菜单栏选择[视图]>[大纲].进入大纲后,对文本设置大纲级别. 2.设置好后,在[word选项]>下拉菜单中找到[不在功能区命令]>选择[发送到PPT].

  9. 2、Linux安装jmeter

    1.下载地址 http://jmeter.apache.org/download_jmeter.cgi 2.选择下载,本地选择,Source版会比较坑 3.安装jdk8,过程省略,可参考:https: ...

  10. Java String类和StringBuffer类的区别

    1.String与StringBuffer的区别简单地说,就是一个变量和常量的关系.StringBuffer对象的内容可以修改:而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象.St ...