1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.hardware.camera2.marshal.impl;
17
18import android.hardware.camera2.marshal.Marshaler;
19import android.hardware.camera2.marshal.MarshalQueryable;
20import android.hardware.camera2.params.ReprocessFormatsMap;
21import android.hardware.camera2.params.StreamConfigurationMap;
22import android.hardware.camera2.utils.TypeReference;
23
24import static android.hardware.camera2.impl.CameraMetadataNative.*;
25import static android.hardware.camera2.marshal.MarshalHelpers.*;
26
27import java.nio.ByteBuffer;
28import java.nio.IntBuffer;
29
30/**
31 * Marshaler for {@code android.scaler.availableInputOutputFormatsMap} custom class
32 * {@link ReprocessFormatsMap}
33 */
34public class MarshalQueryableReprocessFormatsMap
35        implements MarshalQueryable<ReprocessFormatsMap> {
36
37    private class MarshalerReprocessFormatsMap extends Marshaler<ReprocessFormatsMap> {
38        protected MarshalerReprocessFormatsMap(
39                TypeReference<ReprocessFormatsMap> typeReference, int nativeType) {
40            super(MarshalQueryableReprocessFormatsMap.this, typeReference, nativeType);
41        }
42
43        @Override
44        public void marshal(ReprocessFormatsMap value, ByteBuffer buffer) {
45            /*
46             * // writing (static example, DNG+ZSL)
47             * int32_t[] contents = {
48             *   RAW_OPAQUE, 3, RAW16, YUV_420_888, BLOB,
49             *   RAW16, 2, YUV_420_888, BLOB,
50             *   ...,
51             *   INPUT_FORMAT, OUTPUT_FORMAT_COUNT, [OUTPUT_0, OUTPUT_1, ..., OUTPUT_FORMAT_COUNT-1]
52             * };
53             */
54            int[] inputs = StreamConfigurationMap.imageFormatToInternal(value.getInputs());
55            for (int input : inputs) {
56                // INPUT_FORMAT
57                buffer.putInt(input);
58
59                int[] outputs =
60                        StreamConfigurationMap.imageFormatToInternal(value.getOutputs(input));
61                // OUTPUT_FORMAT_COUNT
62                buffer.putInt(outputs.length);
63
64                // [OUTPUT_0, OUTPUT_1, ..., OUTPUT_FORMAT_COUNT-1]
65                for (int output : outputs) {
66                    buffer.putInt(output);
67                }
68            }
69        }
70
71        @Override
72        public ReprocessFormatsMap unmarshal(ByteBuffer buffer) {
73            int len = buffer.remaining() / SIZEOF_INT32;
74            if (buffer.remaining() % SIZEOF_INT32 != 0) {
75                throw new AssertionError("ReprocessFormatsMap was not TYPE_INT32");
76            }
77
78            int[] entries = new int[len];
79
80            IntBuffer intBuffer = buffer.asIntBuffer();
81            intBuffer.get(entries);
82
83            // TODO: consider moving rest of parsing code from ReprocessFormatsMap to here
84
85            return new ReprocessFormatsMap(entries);
86        }
87
88        @Override
89        public int getNativeSize() {
90            return NATIVE_SIZE_DYNAMIC;
91        }
92
93        @Override
94        public int calculateMarshalSize(ReprocessFormatsMap value) {
95            /*
96             * // writing (static example, DNG+ZSL)
97             * int32_t[] contents = {
98             *   RAW_OPAQUE, 3, RAW16, YUV_420_888, BLOB,
99             *   RAW16, 2, YUV_420_888, BLOB,
100             *   ...,
101             *   INPUT_FORMAT, OUTPUT_FORMAT_COUNT, [OUTPUT_0, OUTPUT_1, ..., OUTPUT_FORMAT_COUNT-1]
102             * };
103             */
104            int length = 0;
105
106            int[] inputs = value.getInputs();
107            for (int input : inputs) {
108
109                length += 1; // INPUT_FORMAT
110                length += 1; // OUTPUT_FORMAT_COUNT
111
112                int[] outputs = value.getOutputs(input);
113                length += outputs.length; // [OUTPUT_0, OUTPUT_1, ..., OUTPUT_FORMAT_COUNT-1]
114            }
115
116            return length * SIZEOF_INT32;
117        }
118    }
119
120    @Override
121    public Marshaler<ReprocessFormatsMap> createMarshaler(
122            TypeReference<ReprocessFormatsMap> managedType, int nativeType) {
123        return new MarshalerReprocessFormatsMap(managedType, nativeType);
124    }
125
126    @Override
127    public boolean isTypeMappingSupported(TypeReference<ReprocessFormatsMap> managedType,
128            int nativeType) {
129        return nativeType == TYPE_INT32 && managedType.getType().equals(ReprocessFormatsMap.class);
130    }
131}
132