安卓版的pvr图片查看
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图片查看的更多相关文章
- 微信5.4安卓版重回ios风格 导航菜单都放底栏位置
微信5.4安卓版发布更新了,由于本人的手机设置软件自动更新,中午的时候才发现微信换成了5.4版本,启动微信后是一个大大的“转账,就是发消息”,进入微信界面有点小惊喜,导航菜单都改为底部tab方式,顶部 ...
- 浩瀚技术 安卓版移动开单手持微POS PDA无线移动开单软件 -安卓版移动手持开单设备
PDA数据采集器,是深圳浩瀚技术有限公司最新研发的一款安卓版移动手持开单设备,它通过WIFI和GPRS连接并访问电脑,从进销存软件中读取数据,实现移动开单,打破电脑开单模式. 它自带扫描器,可直接扫描 ...
- 中国首个 SaaS 模式的云告警平台安卓版 APP 上线
今年一月底,国内首个 SaaS 模式的云告警平台 OneAlert 正式发布了 iOS 版 App 客户端,今天上午,安卓版 App 客户端也正式上线了!每个安卓用户,无需电脑,都可以通过手机全程跟踪 ...
- SQLSERVER图片查看工具SQL Image Viewer5.5.0.156
原文:SQLSERVER图片查看工具SQL Image Viewer5.5.0.156 SQLSERVER图片查看工具SQL Image Viewer5.5.0.156 在2013年某一次北京SQL ...
- 2017年05月10日记一次微项目投产 | 安卓版微信内置浏览器不能解析gzip压缩过的mp4视频的问题
前言 今天投产了一个小项目,一个很简单的H5,有播放视频功能,使用了videojs插件. 之前也做过数个视频播放,视频的转压都按照既定流程进行,文件放到FTP后,iphone和安卓机测试下来都没有问题 ...
- 一款基于 Android 开发的离线版的 MM 图片浏览 App
一款离线版的 MM 图片浏览 App,有点类似掌上百度的图片专栏应用.图片采用瀑布流展示方式,点击图片集,支持左右手势滑动切换图片:支持放大缩小功能. 实现功能:1)图片完全离线,不耗个人 GPRS ...
- Win10默认图片查看器更改
Win10自带的图片查看器不是很习惯,其背景乌漆嘛黑,宽扁的额头让人想起了黑边火腿肠手机,无法直视.怀念Win7和Win8.1的图片查看器,一个鼠标滚轮缩放自如的酸爽感觉.但却遗憾地发现,并不能直观地 ...
- 基于JQUERY 的图片查看插件
viewer是一款功能强大的图片查看器.它可以实现ACDsee等看图软件的部分功能.它可以对图片进行移动,缩放,旋转,翻转,可以前后浏览一组图片.该图片查看器还支持移动设备,支持键盘控制,功能十分强大 ...
- 强大的jQuery图片查看器插件Viewer.js
简介 Viewer.js 是一款强大的图片查看器 Viewer.js 有以下特点: 支持移动设备触摸事件 支持响应式 支持放大/缩小 支持旋转(类似微博的图片旋转) 支持水平/垂直翻转 支持图片移动 ...
随机推荐
- jmeter 上传附件脚本报Non HTTP response code: java.io.FileNotFoundException
如果上传附件报如下错误,就需要把附件放到和脚本同一路径下就解决了
- 20155219付颖卓《网络对抗》MSF基础应用实验
实验后回答问题 1.用自己的话解释什么是exploit,payload,encode. exploit就是进行攻击的那一步 payload是在目标主机上创建会话连接的 encode是对payload进 ...
- 加载xib文件,如果想在初始化的时候就添加点东西就重载-(id)initWithCoder:(NSCoder *)aDecoder
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { self.cl ...
- 利用位运算进行a+b的计算(Java&&Python)
题目链接 需要用到的位运算操作:异或(^).与(&).右移(<<) 异或运算:又称不进位加法,a^b得到的结果为a与b相加,但是需要进位的地方不进位得到的结果 与运算:找出来a和b ...
- 20164322 韩玉婷-----Exp5 MSF基础应
Exp5 MSF基础应用 1.基础问题回答 exploit: 是指攻击者或渗透测试者利用一个系统.应用或服务中的安全漏洞所进行的攻击行为, 包括利用缓冲区溢出.Web应用程序漏洞攻击,以及利用配置错误 ...
- day11.3分页操作divmod
# 分页显示 divmod(被除数,除数) INFO_LIST = [] for i in range(836): template = "第%s天,笨笨先僧 always be there ...
- C#取出重复的方式以及用字典存储以键存储集合的方法
最近在做项目的时候,发现有些需求需要特别的方式来实现.下面看代码 private List<string> firstType = new List<string>(); pr ...
- 兄弟连学python---网络简介
网络简介 1.什么是网络 网络是辅助双方能够连接在一起的工具 使用网络的目的 为了联通多方然后进行通讯,能够让软件在不同的电脑上运行,相互传输数据 网络的发展 网络协议 什么是协议 约定俗成的,没有理 ...
- Custom Default Node Colors and Shapes in Houdini 16.5
A:before H16.5: 1.Create a file, named OPcustomize 2.Edit it like this: //Custom Default Shapes opde ...
- 常用java的正则表达式
package everyDayPratise; import java.util.regex.Pattern; public class RegexExample { public static v ...