public class PVRTDecompress
{
/*
author:FormatFa
mail :1758759399@qq.com
date :2017-6-14
*/ //modify from PVRTDecompress.cpp in PowerVR
//https://github.com/gildor2/UModel libs dir public static int Version3 = 0x03525650; static int ETC_FLIP = 0x01000000;
static int ETC_DIFF = 0x02000000; static int[][] mod= new int[][]{
{2, 8, -2, -8},
{5, 17, -5, -17},
{9, 29, -9, -29},
{13, 42, -13, -42},
{18, 60, -18, -60},
{24, 80, -24, -80},
{33, 106, -33, -106},
{47, 183, -47, -183}
}; /*
PvrtHeader info from PVR File Format Specification.pdf */
public static int flag_NoFlag=0x0;
//When this flag is set, colour values within the texture have been pre- multiplied by the alpha values public static int flag_premultiplied=0x02; //Texture data is in the Linear RGB colour space
public static int colorSpace_LinearRGB=0;
//Texture data is in the Standard RGB colour space
public static int colorSpace_aRGB=1;
public static int channel_UnsignedByteNormalised=0; public static long format_ETC2_RGB=0x00000016; public static class PVRTHeader
{
public int version;
public int flags;
public long pixelFormat;
//int piexlFormat2;
public int colorSpace;
public int channelType;
public int width;
public int heigth;
public int depth;
public int numSurface;
public int numFace;
public int minMapCount;
public int metaDataSize; public byte[] imgdata; @Override
public String toString()
{ return "version:"+Integer.toHexString(version)
+"\nflag:"+Integer.toHexString(flags)
+"\npiex:"+Long.toHexString(pixelFormat)
+"\ncolor:"+Integer.toHexString(colorSpace)
+"\nchannal:"+Integer.toHexString(channelType)
+"\nwdth:"+Integer.toHexString(width)
+"\nheigth:"+Integer.toHexString(heigth)
+"\nsurface:"+Integer.toHexString(numSurface)
+"\nface:"+Integer.toHexString(numFace)
+"\nminp:"+Integer.toHexString(minMapCount)
+"\nmeta:"+Integer.toHexString(metaDataSize); } } void pri(int l)
{ } public static PVRTHeader loadPVRHeader(InputStream is) throws Exception
{ PVRTHeader head = new PVRTHeader(); //if(head.version!=Version3)
// throw new Exception("magic except:"+Integer.toHexString(head.version); MyDataInputStream my = new MyDataInputStream(is); head.version = my.readInt(); head.flags = my.readInt(); head.pixelFormat = my.readLong(); head.colorSpace = my.readInt(); head.channelType = my.readInt();
head.width = my.readInt();
head.heigth= my.readInt();
head.depth = my.readInt();
head.numSurface = my.readInt();
head.numFace = my.readInt();
head.minMapCount = my.readInt();
head.metaDataSize = my.readInt(); is.skip(head.metaDataSize);
byte[] data = new byte[my.available()];
my.readFully(data); head.imgdata = data;
return head; } public static int[] PVRTDecompressETC_int(PVRTHeader head)
{ List<Integer> t=new ArrayList<Integer>(); int[] piex=new int[head.width*head.heigth]; long blockTop,blockBot;
long modtable1,modtable2; boolean bFlip,bDiff; char red1,green1,blue1;
char red2,green2,blue2; int offset=0;
int mark = 0; int w = head.width;
int h = head.heigth; byte[] data = head.imgdata; for(int i = 0 ; i < h;i+=4)
{ for(int j = 0; j<w;j+=4)
{ int p = offset;
mark = i*w+j; blockTop = ByteUtils.byte2intLow(new byte[]{data[p],data[p+1],data[p+2],data[p+3]});
blockBot = ByteUtils.byte2intLow(new byte[]{data[p+4],data[p+5],data[p+6],data[p+7]});
// System.out.println(Integer.toHexString((int)blockTop)+" "+Integer.toHexString((int)blockBot)); offset+=8; bFlip = ((blockTop&ETC_FLIP)!=0);
bDiff = (blockTop&ETC_DIFF)!=0; if(bDiff)
{ blue1 =(char) ((blockTop & 0xf80000) >> 16);
green1 = (char)((blockTop & 0xf800) >> 8);
red1 = (char)(blockTop & 0xf8);
// System.out.println("greeqn:"+(int)green1+",:"+(int)blue1+","+(int)red1); //in c is signed char,
// get differential colour for subblock 2
char blues = (char)((blue1 >> 3) +(char) (((blockTop & 0x70000) >> 11) >> 5));
char greens=( (char)( (green1 >> 3 )+ ( ((blockTop & 0x700) >> 3) >> 5))); char reds =(char)( (red1 >> 3) + ( ((blockTop & 0x7) << 5) >> 5));
// System.out.println("b:"+blockTop+ "sgreeqn:"+(int)greens+",:"+(int)blues+","+(int)reds); blue2 = blues;
green2 = greens;
red2 = reds;
if(offset<120&&bFlip)
//
System.out.println( (int)red1+"trs:"+(int)reds+"-- "+blockTop+ "_yes:"+ (int)red2+","+(int)green2+","+(int) blue2);
//
red1 =(char)( red1 + (red1 >> 5)); // copy bits to lower sig
green1 = (char)( green1 + (green1 >> 5)); // copy bits to lower sig
blue1 = (char)( blue1 + (blue1 >> 5)); // copy bits to lower sig red2 = (char)( (red2 << 3) + (red2 >> 2)); // copy bits to lower sig
green2 = (char)( (green2 << 3) + (green2 >> 2)); // copy bits to lower sig
blue2 = (char)( (blue2 << 3) + (blue2 >> 2)); // copy bits to lower sig }
else
{
//System.out.println("diff");
// individual mode 4 + 4 colour bits
// get base colour for subblock 1
blue1 =(char) ((blockTop & 0xf00000) >> 16);
blue1 =(char) ( blue1 + (blue1 >> 4)); // copy bits to lower sig
green1 =(char) (int)((blockTop & 0xf000) >> 8);
green1 =(char) ( green1 + (green1 >> 4)); // copy bits to lower sig
red1 = (char) (int)(blockTop & 0xf0);
red1 =(char) (red1 + (red1 >> 4)); // copy bits to lower sig // get base colour for subblock 2
blue2 =(char) (int)((blockTop & 0xf0000) >> 12);
blue2 = (char)( blue2 + (blue2 >> 4)); // copy bits to lower sig
green2 =(char) (int)((blockTop & 0xf00) >> 4);
green2 = (char)(green2 + (green2 >> 4)); // copy bits to lower sig
red2 =(char)(int) ((blockTop & 0xf) << 4);
red2 = (char)(red2 + (red2 >> 4)); // copy bits to lower sig
// System.out.println("b:"+blockTop+"greeqn:"+(int)green2+",:"+(int)blue2+","+(int)red2); } // get the modtables for each subblock
modtable1 = (blockTop >> 29) & 0x7;
modtable2 = (blockTop >> 26) & 0x7; if(!bFlip)/* 2*4 block */
{ for (int a = 0; a< 4; a++) // vertical
{
for (int b = 0; b < 2; b++) // horizontal
{
//*(output + j * x + k) = //
piex[mark+ a*w+b]=(modifyPixel((int)red1, (int)green1, (int)blue1, b, a, blockBot, (int)modtable1));
//*(output + j * x + k + 2) = piex[ mark+ a*w+b+2]=
// piex[mark+ a*w+b];
(modifyPixel((int)red2, (int)green2,(int) blue2, b + 2, a, blockBot, (int)modtable2)); //if(offset<120)
// System.out.println("no:"+piex[ mark+ a*w+b+2]); }
} }
else/*flip*/
{ for (int a = 0; a< 2; a++) // vertical
{
for (int b = 0; b < 4; b++) // horizontal
{ //*(output + j * x + k) =
piex[ mark+ a*w+b]=(modifyPixel((int)red1, (int)green1, (int)blue1, b, a, blockBot, (int)modtable1)); //*(output + j * x + k + 2) =
piex[ mark+ (a+2)*w+b]=
// piex[ mark+ a*w+b];
(modifyPixel((int)red2, (int)green2,(int) blue2, b ,a+2, blockBot, (int)modtable2));
//
if(offset<120)
//
System.out.println( bDiff+ "_yes:"+ (int)red2+","+(int)green2+","+(int) blue2+","+b+" ,"+(a+2) +":->"+piex[ mark+ (a+2)*w+b]);
//
}
}
} } } return piex; }
/* Decompress to ARGB8888 */
public static byte[] PVRTDecompressETC(PVRTHeader head) throws IOException
{ int[] pix = PVRTDecompressETC_int(head); ByteArrayOutputStream os = new ByteArrayOutputStream(); MyDataOutPutStream myos = new MyDataOutPutStream(os);
for(int p :pix)
myos.writeInt(p);
return ((ByteArrayOutputStream) myos.getOuputStream()).toByteArray(); } /* !***********************************************************************
@Function modifyPixel
@Input red Red value of pixel
@Input green Green
value of pixel
@Input blue Blue value of pixel
@Input x Pixel x position
in block @Input y Pixel y position in block
@Input modBlock Values for the
current block
@Input modTable Modulation value
s @Returns Returns actual
pixel colour
@Description Used by ETCTextureDecompress
************************************************************************ */
static int modifyPixel(int red, int green, int blue, int x, int y,
long modBlock, int modTable) {
int index = x * 4 + y, pixelMod;
long mostSig = modBlock << 1; if (index < 8)
pixelMod =
mod[modTable][(int)(((modBlock >> (index + 24)) & 0x1) +
((mostSig >> (index + 8)) & 0x2))];
else
pixelMod =
mod[modTable][(int)(((modBlock >> (index + 8)) & 0x1) +
((mostSig >> (index - 8)) & 0x2))]; red = _CLAMP_(red + pixelMod, 0, 255);
green = _CLAMP_(green + pixelMod, 0, 255);
blue = _CLAMP_(blue + pixelMod, 0, 255); return ((red << 16) + (green << 8) + blue) | 0xff000000;
} private static int _CLAMP_(int pixelMod, int p1, int p2)
{
return (pixelMod)<(p2)? ((pixelMod)<(p1)?(p1):(pixelMod) ) : (p2);
} }

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

    int[] data=PVRTDecompress.PVRTDecompressETC_int(he);
Bitmap bmp= Bitmap.createBitmap(data, he.width,he.heigth,Bitmap.Config.ARGB_8888);
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. vue生命周期图片

  2. jmeter使用手册

    1.在bin文件中找到jmeter.bat文件启动 2.创建测试计划-填写计划名称 3.添加线程组(右键点击) 4.设置线程-红框内均可设置,线程数-并发次数 5.在线程组下添加http请求 6.在h ...

  3. Python:从入门到实践--第十一章--测试代码--练习

    #1.城市和国家:编写一个函数,它接受两个形参:一个城市名和一个国家名. #这个函数返回一个格式为City,Country的字符串,如Santiago,Chile.将这个函数 #存储在一个名为city ...

  4. pycharm配置tensorflow环境 适用于Python3.6 CPU

    一.环境 基于安装Python3.6以及pycharm. 二.在项目设置里配置编译环境 打开pycharm新建一个项目. 打开pycharm->file->setting->proj ...

  5. 关于mysql设置外键,实现参照性完整性约束,以及workbench上的一个bug(?)

    一.本次数据库中有student,course,sc表,其设置情况 -- 创建course表 CREATE TABLE `course` ( `cno` ) NOT NULL, `cname` ) D ...

  6. PAT乙级考前总结(五)

    字符串处理 1003 我要通过! (20 分) “答案正确”是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否 ...

  7. [删括号][判断可行性的dp]

    链接:https://ac.nowcoder.com/acm/problem/21303来源:牛客网题目描述 给你一个合法的括号序列s1,每次你可以删除一个"()" 你可以删除0个 ...

  8. Javascript 4.3 事件处理函数

    鼠标指针悬停在某个元素上时触发一个动作:onmouseover事件处理函数 鼠标指针离开某个元素时触发一个动作:onmouseout事件处理函数 点击某个链接时触发一个动作:onclick事件处理函数 ...

  9. 【scrapy】笔记一:安装,以及遇到的坑

    一.前提 环境:python 3.7 操作系统: windows ;mac 二.安装步骤 mac : pip3 install scarpy //因为MAC自带python2.7所有我们用pip3指定 ...

  10. Python 安装beautifulsoup4遇到No module named setuptools问题解决方法

    背景说明: 电脑win7-32 在Python 3.3.5下安装beautifulsoup4 4.6.0(下载链接https://pypi.org/project/beautifulsoup4/#fi ...