1+ package li.auna.patches.instagram.misc.quality
2+
3+ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
4+ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
5+ import app.revanced.patcher.extensions.InstructionExtensions.instructions
6+ import app.revanced.patcher.patch.bytecodePatch
7+ import com.android.tools.smali.dexlib2.Opcode
8+ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
9+ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
10+
11+ @Suppress(" unused" )
12+ val maxMediaQualityPatch = bytecodePatch(
13+ name = " Max Media Quality" ,
14+ description = " Enable max media quality." ,
15+ ) {
16+ compatibleWith(
17+ " com.instagram.android"
18+ )
19+
20+ execute {
21+ val maxPostSize = " 2048" // Maximum post size.
22+ val maxBitRate = " 10000000" // Maximum bit rate possible (found in code).
23+
24+ // Improve quality of images.
25+ // Instagram tend to reduce/compress the image resolution to user's device height and width.
26+ // This section of code removes that restriction and sets the resolution to 2048x2048 (max possible).
27+ displayMetricsFingerprint.let { it ->
28+ it.method.apply {
29+ val displayMetInstructions = instructions.filter { it.opcode == Opcode .IGET }
30+
31+ // There are 3 iget instances.
32+ // 1.dpi 2.width 3.height.
33+ // We don't need to change dpi, we just need to change height and width.
34+ displayMetInstructions.drop(1 ).forEach { instruction ->
35+ val index = instruction.location.index
36+ val register = getInstruction<TwoRegisterInstruction >(index).registerA
37+
38+ // Set height and width to 2048.
39+ addInstruction(index + 1 , " const v$register , $maxPostSize " )
40+ }
41+ }
42+ }
43+
44+ // Yet another method where the image resolution is compressed.
45+ mediaSizeFingerprint.let { it ->
46+ it.classDef.apply {
47+ val mediaSetMethod =
48+ methods.first { it.returnType == " Lcom/instagram/model/mediasize/ExtendedImageUrl;" }
49+
50+ val mediaSetInstructions =
51+ mediaSetMethod.instructions.filter { it.opcode == Opcode .INVOKE_VIRTUAL }
52+
53+ mediaSetInstructions.forEach { instruction ->
54+ val index = instruction.location.index + 1
55+ val register = mediaSetMethod.getInstruction<OneRegisterInstruction >(index).registerA
56+
57+ // Set height and width to 2048.
58+ mediaSetMethod.addInstruction(index + 1 , " const v$register , $maxPostSize " )
59+ }
60+ }
61+ }
62+
63+ // Improve quality of stories.
64+ // This section of code sets the bitrate of the stories to the maximum possible.
65+ storyMediaBitrateFingerprint.let { it ->
66+ it.method.apply {
67+ val ifLezIndex = instructions.first { it.opcode == Opcode .IF_LEZ }.location.index
68+
69+ val bitRateRegister = getInstruction<OneRegisterInstruction >(ifLezIndex).registerA
70+
71+ // Set the bitrate to maximum possible.
72+ addInstruction(ifLezIndex + 1 , " const v$bitRateRegister , $maxBitRate " )
73+ }
74+ }
75+
76+ // Improve quality of reels.
77+ // In general Instagram tend to set the minimum bitrate between maximum possible and compressed video's bitrate.
78+ // This section of code sets the bitrate of the reels to the maximum possible.
79+ videoEncoderConfigFingerprint.let { it ->
80+ it.classDef.apply {
81+ // Get the constructor.
82+ val videoEncoderConfigConstructor = methods.first()
83+
84+ val lastMoveResIndex = videoEncoderConfigConstructor.instructions
85+ .last { it.opcode == Opcode .MOVE_RESULT }.location.index
86+
87+ // Finding the register were the bitrate is stored.
88+ val bitRateRegister =
89+ videoEncoderConfigConstructor.getInstruction<OneRegisterInstruction >(lastMoveResIndex).registerA
90+
91+ // Set bitrate to maximum possible.
92+ videoEncoderConfigConstructor.addInstruction(
93+ lastMoveResIndex + 1 ,
94+ " const v$bitRateRegister , $maxBitRate " ,
95+ )
96+ }
97+ }
98+ }
99+ }
0 commit comments