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. 聊聊pytorch中的DataLoader

    实际上pytorch在定义dataloader的时候是需要传入很多参数的,比如,number_workers, pin_memory, 以及shuffle, dataset等,其中sampler参数算 ...

  2. 锦囊9-if语句

    [程序描述] 编写程序,通过使用 if...elif...else 语句判断数字是正数.负数或零: [程序分析] 正数.负数或零的判断非常简单,只需要判断这个数是否大于零,小于零或者等于零.由于判断的 ...

  3. 手机连接fiddler之后,安装证书的方法

    1. 手机设置锁屏密码2. 手机连接fiddler测试网络3. 手机访问    电脑IP:fiddler设置的端口号4. 点击页面中的链接,下载并安装证书,随意命名即可 (还不清楚证书有啥用,先记录下 ...

  4. 取MySQL结果集的第一条记录

    select * FROM SU_supplycontract t WHERE supplyContractCode="CRM20180813002" limit 1;

  5. 我的代码-normalize

    # coding: utf-8 # In[13]: import pandas as pdimport numpy as npimport scipy as spfrom os import list ...

  6. spring3-struts2整合

    spring  负责对象创建 struts   用Action处理请求 说明: spring版本:spring-framework-3.2.5.RELEASE struts版本:struts-2.3. ...

  7. MySQL-02-进阶

    大纲 1)数据约束 2)数据库设计(表设计) 3)存储过程 4)触发器 5)mysql权限问题 数据约束 2.1什么数据约束 对用户操作表的数据进行约束 2.2 默认值 作用: 当用户对使用默认值的字 ...

  8. js中substr、substring、slice的区别

    substr(start, length) substring(from, to) slice(from, to) 以上函数只传一个参数时,认为是起始位置,然后按照正方向截取 substring的参数 ...

  9. LibreOffice字体问题解决;从window复制到Ubuntu

    拷贝或下载windows系统的Fonts字体集到对应的linux系统下;以ubuntu16.04系统为例. 1.进入windows系统,到C:WindowsFonts目录,复制拷贝自己需要的字体(也可 ...

  10. cf374C Inna and Dima dfs判环+求最长链

    题目大意是有一个DIMA四种字母组成的矩阵,要在矩阵中找最长的DIMADIMADIMA……串,连接方式为四方向连接,问最长能找到多少DIMA.字母可以重复访问,如果DIMA串成环,即可以取出无限长的D ...